Merge remote-tracking branch 'origin/3.4.x' into 4.0.x

This commit is contained in:
William Cheng 2018-11-15 17:49:44 +08:00
commit 2bcf5b2263
581 changed files with 32821 additions and 958 deletions

View File

@ -122,8 +122,8 @@ script:
# fail if generators contain tab '\t'
- /bin/bash ./bin/utils/detect_tab_in_java_class.sh
# run integration tests defined in maven pom.xml
- mvn --quiet clean install
- mvn --quiet verify -Psamples
- ./run-in-docker.sh mvn --quiet --batch-mode clean install
- mvn --quiet --batch-mode verify -Psamples
after_success:
# push to maven repo
- if [ $SONATYPE_USERNAME ] && [ -z $TRAVIS_TAG ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
@ -148,7 +148,7 @@ after_success:
## docker: build and push openapi-generator-online to DockerHub
- if [ $DOCKER_HUB_USERNAME ]; then echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin && docker build -t $DOCKER_GENERATOR_IMAGE_NAME ./modules/openapi-generator-online && if [ ! -z "$TRAVIS_TAG" ]; then docker tag $DOCKER_GENERATOR_IMAGE_NAME:latest $DOCKER_GENERATOR_IMAGE_NAME:$TRAVIS_TAG; fi && if [ ! -z "$TRAVIS_TAG" ] || [ "$TRAVIS_BRANCH" = "master" ]; then docker push $DOCKER_GENERATOR_IMAGE_NAME && echo "Pushed to $DOCKER_GENERATOR_IMAGE_NAME"; fi; fi
## docker: build cli image and push to Docker Hub
- if [ $DOCKER_HUB_USERNAME ]; then echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin && docker build -t $DOCKER_CODEGEN_CLI_IMAGE_NAME ./modules/openapi-generator-cli && if [ ! -z "$TRAVIS_TAG" ]; then docker tag $DOCKER_CODEGEN_CLI_IMAGE_NAME:latest $DOCKER_CODEGEN_CLI_IMAGE_NAME:$TRAVIS_TAG; fi && if [ ! -z "$TRAVIS_TAG" ] || [ "$TRAVIS_BRANCH" = "master" ]; then docker push $DOCKER_CODEGEN_CLI_IMAGE_NAME && echo "Pushed to $DOCKER_CODEGEN_CLI_IMAGE_NAME"; fi; fi
- if [ $DOCKER_HUB_USERNAME ]; then echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin && cp docker-entrypoint.sh ./modules/openapi-generator-cli && docker build -t $DOCKER_CODEGEN_CLI_IMAGE_NAME ./modules/openapi-generator-cli && if [ ! -z "$TRAVIS_TAG" ]; then docker tag $DOCKER_CODEGEN_CLI_IMAGE_NAME:latest $DOCKER_CODEGEN_CLI_IMAGE_NAME:$TRAVIS_TAG; fi && if [ ! -z "$TRAVIS_TAG" ] || [ "$TRAVIS_BRANCH" = "master" ]; then docker push $DOCKER_CODEGEN_CLI_IMAGE_NAME && echo "Pushed to $DOCKER_CODEGEN_CLI_IMAGE_NAME"; fi; fi
env:
- DOCKER_GENERATOR_IMAGE_NAME=openapitools/openapi-generator-online DOCKER_CODEGEN_CLI_IMAGE_NAME=openapitools/openapi-generator-cli NODE_ENV=test CC=gcc-5 CXX=g++-5

View File

@ -2,16 +2,11 @@
<div align="center">
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`3.3.2`): [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/master.svg?label=Integration%20Test)](https://travis-ci.org/OpenAPITools/openapi-generator)
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`3.3.3`): [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/master.svg?label=Integration%20Test)](https://travis-ci.org/OpenAPITools/openapi-generator)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Run Status](https://api.shippable.com/projects/5af6bf74e790f4070084a115/badge?branch=master)](https://app.shippable.com/github/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=master&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
[`3.4.x`](https://github.com/OpenAPITools/openapi-generator/tree/3.4.x) branch: [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/3.4.x.svg?label=Integration%20Test)](https://travis-ci.org/OpenAPITools/openapi-generator)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator/tree/3.4.x.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Run Status](https://api.shippable.com/projects/5af6bf74e790f4070084a115/badge?branch=3.4.x)](https://app.shippable.com/github/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=3.4.x&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
[`4.0.x`](https://github.com/OpenAPITools/openapi-generator/tree/4.0.x) branch: [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/4.0.x.svg?label=Integration%20Test)](https://travis-ci.org/OpenAPITools/openapi-generator)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator/tree/4.0.x.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Run Status](https://api.shippable.com/projects/5af6bf74e790f4070084a115/badge?branch=4.0.x)](https://app.shippable.com/github/OpenAPITools/openapi-generator)
@ -88,10 +83,9 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
OpenAPI Generator Version | Release Date | Notes
---------------------------- | ------------ | -----
4.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/4.0.0-SNAPSHOT/)| TBD | Major release with breaking changes (no fallback)
3.4.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/3.4.0-SNAPSHOT/)| 01.11.2018 | Minor release (breaking changes with fallbacks)
3.3.3 (current master, upcoming patch release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/3.3.3-SNAPSHOT/) | 15.11.2018 | Bugfix release
[3.3.2](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.3.2) (latest stable release) | 31.10.2018 | Bugfix release
4.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/4.0.0-SNAPSHOT/)| 20.12.2018 | Major release with breaking changes (with or without fallback)
3.3.4 (current master, upcoming patch release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/3.3.4-SNAPSHOT/) | 01.12.2018 | Bugfix release
[3.3.3](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.3.3) (latest stable release) | 15.11.2018 | Bugfix release
OpenAPI Spec compatibility: 1.0, 1.1, 1.2, 2.0, 3.0
@ -147,16 +141,16 @@ See the different versions of the [openapi-generator-cli](https://mvnrepository.
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum):
JAR location: `http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.2/openapi-generator-cli-3.3.2.jar`
JAR location: `http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.3/openapi-generator-cli-3.3.3.jar`
For **Mac/Linux** users:
```sh
wget http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.2/openapi-generator-cli-3.3.2.jar -O openapi-generator-cli.jar
wget http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.3/openapi-generator-cli-3.3.3.jar -O openapi-generator-cli.jar
```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
```
Invoke-WebRequest -OutFile openapi-generator-cli.jar http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.2/openapi-generator-cli-3.3.2.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.3/openapi-generator-cli-3.3.3.jar
```
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.

View File

@ -0,0 +1,17 @@
#!/bin/sh
# C# Petstore API client (.NET 3.5)
./bin/csharp-refactor-petstore.sh
# C# Petstore API client with PropertyChanged
./bin/csharp-refactor-property-changed-petstore.sh
# C# Petstore API client (v5.0 for .net standarnd 1.3+)
./bin/csharp-refactor-petstore-net-standard.sh
# C# Petstore API client (.NET 4.0)
./bin/csharp-refactor-petstore-net-40.sh
# C# Petstore API client (.NET 3.5)
./bin/csharp-refactor-petstore-net-35.sh

37
bin/csharp-refactor-petstore.sh Executable file
View File

@ -0,0 +1,37 @@
#!/bin/sh
SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
if [ ! -f "$executable" ]
then
mvn -B clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g csharp-refactor -o samples/client/petstore/csharp-refactor/OpenAPIClient --additional-properties packageGuid={321C8C3F-0156-40C1-AE42-D59761FB9B6C} $@"
java $JAVA_OPTS -jar $executable $ags
# restore csproj file
#echo "restore csproject file: CI/samples/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj"
#cp ./CI/samples.ci/client/petstore/csharp/OpenAPIClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj ./samples/client/petstore/csharp-refactor/OpenAPIClient/src/Org.OpenAPITools.Test/

View File

@ -0,0 +1,28 @@
#!/bin/bash
#
# A script to test all generators to ensure there's no Java exception when running it with OAS 2.0, 3.0 fake petstore spec
#
SCRIPT="$0"
echo "# START SCRIPT: ${SCRIPT}"
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
for GENERATOR in $(java -jar ${executable} list --short | sed -e 's/,/\'$'\n''/g')
do
if eval java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/2.0/${GENERATOR} > /dev/null 2>&1; then
echo "[OAS 2.0] Executed ${GENERATOR} successfully!"
else
echo "ERROR: Failed to run ${GENERATOR}"
echo "java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/2.0/${GENERATOR}"
exit 1
fi
if eval java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/3.0/${GENERATOR} > /dev/null 2>&1; then
echo "[OAS 3.0] Executed ${GENERATOR} successfully!"
else
echo "ERROR: Failed to run ${GENERATOR}"
echo "java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/3.0/${GENERATOR}"
exit 1
fi
done

View File

@ -19,6 +19,9 @@ CONFIG OPTIONS for kotlin-server
enumPropertyNaming
Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original' (Default: camelCase)
parcelizeModels
toggle "@Parcelize" for generated models
library
library template (sub-template) to use (Default: ktor)
ktor - ktor framework

View File

@ -19,6 +19,9 @@ CONFIG OPTIONS for kotlin-spring
enumPropertyNaming
Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original' (Default: camelCase)
parcelizeModels
toggle "@Parcelize" for generated models
title
server title name or client service name (Default: OpenAPI Kotlin Spring)

View File

@ -19,6 +19,9 @@ CONFIG OPTIONS for kotlin
enumPropertyNaming
Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original' (Default: camelCase)
parcelizeModels
toggle "@Parcelize" for generated models
dateLibrary
Option. Date library to use
string - String

View File

@ -9,6 +9,8 @@ cd modules/openapi-generator-online
mvn spring-boot:run
```
:bulb: The online openapi-generator can be run via [Docker](https://github.com/OpenAPITools/openapi-generator#16---docker) as well.
For example, to generate Ruby API client, simply send the following HTTP request using curl:
```sh
curl -X POST -H "content-type:application/json" -d '{"openAPIUrl":"https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml"}' http://localhost:8080/api/gen/clients/ruby

View File

@ -1,7 +1,11 @@
FROM java:8-jre-alpine
ADD target/openapi-generator-cli.jar /opt/openapi-generator-cli/openapi-generator-cli.jar
RUN apk add --no-cache bash
ENTRYPOINT ["java", "-jar", "/opt/openapi-generator-cli/openapi-generator-cli.jar"]
ADD target/openapi-generator-cli.jar /opt/openapi-generator/modules/openapi-generator-cli/target/openapi-generator-cli.jar
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["help"]

View File

@ -48,7 +48,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "org.openapitools:openapi-generator-gradle-plugin:3.3.2"
classpath "org.openapitools:openapi-generator-gradle-plugin:3.3.3"
}
}

View File

@ -17,5 +17,5 @@ gradle generateGoWithInvalidSpec
The samples can be tested against other versions of the plugin using the `openApiGeneratorVersion` property. For example:
```bash
gradle -PopenApiGeneratorVersion=3.3.2 openApiValidate
gradle -PopenApiGeneratorVersion=3.3.3 openApiValidate
```

View File

@ -1 +1 @@
openApiGeneratorVersion=3.3.2
openApiGeneratorVersion=3.3.3

View File

@ -11,7 +11,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.3.2</version>
<version>3.3.3</version>
<executions>
<execution>
<goals>

View File

@ -12,7 +12,7 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.3.2</version>
<version>3.3.3</version>
<executions>
<execution>
<goals>

View File

@ -12,7 +12,7 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.3.2</version>
<version>3.3.3</version>
<executions>
<execution>
<goals>

View File

@ -12,7 +12,7 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.3.2</version>
<version>3.3.3</version>
<executions>
<execution>
<goals>

View File

@ -221,6 +221,10 @@ public class CodegenConstants {
public static final String SOURCECODEONLY_GENERATION = "generateSourceCodeOnly";
public static final String SOURCECODEONLY_GENERATION_DESC = "Specifies that only a library source code is to be generated.";
public static final String PARCELIZE_MODELS = "parcelizeModels";
public static final String PARCELIZE_MODELS_DESC = "toggle \"@Parcelize\" for generated models";
// Not user-configurable. System provided for use in templates.
public static final String GENERATE_APIS = "generateApis";

View File

@ -2985,6 +2985,12 @@ public class DefaultCodegen implements CodegenConfig {
LOGGER.warn("Unknown parameter type: " + parameter.getName());
}
// default to UNKNOWN_PARAMETER_NAME if paramName is null
if (codegenParameter.paramName == null) {
LOGGER.warn("Parameter name not defined properly. Default to UNKNOWN_PARAMETER_NAME");
codegenParameter.paramName = "UNKNOWN_PARAMETER_NAME";
}
// set the parameter excample value
// should be overridden by lang codegen
setParameterExampleValue(codegenParameter, parameter);

View File

@ -170,7 +170,6 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
config.additionalProperties().put(CodegenConstants.EXCLUDE_TESTS, true);
}
if (System.getProperty("debugOpenAPI") != null) {
Json.prettyPrint(openAPI);
} else if (System.getProperty("debugSwagger") != null) {
@ -524,10 +523,31 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
operation.put("importPath", config.toApiImport(tag));
operation.put("classFilename", config.toApiFilename(tag));
if (allModels == null || allModels.isEmpty()) {
operation.put("hasModel", false);
} else {
operation.put("hasModel", true);
}
if (!config.vendorExtensions().isEmpty()) {
operation.put("vendorExtensions", config.vendorExtensions());
}
// process top-level x-group-parameters
if (config.vendorExtensions().containsKey("x-group-parameters")) {
Boolean isGroupParameters = Boolean.valueOf(config.vendorExtensions().get("x-group-parameters").toString());
Map<String, Object> objectMap = (Map<String, Object>) operation.get("operations");
@SuppressWarnings("unchecked")
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
for (CodegenOperation op : operations) {
op.httpMethod = op.httpMethod.toLowerCase(Locale.ROOT);
if (!op.vendorExtensions.containsKey("x-group-parameters")) {
op.vendorExtensions.put("x-group-parameters", Boolean.TRUE);
}
}
}
// Pass sortParamsByRequiredFlag through to the Mustache template...
boolean sortParamsByRequiredFlag = true;
if (this.config.additionalProperties().containsKey(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG)) {
@ -1032,13 +1052,16 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
List<Map<String, String>> imports = new ArrayList<Map<String, String>>();
Set<String> mappingSet = new TreeSet<>();
for (String nextImport : allImports) {
Map<String, String> im = new LinkedHashMap<String, String>();
String mapping = config.importMapping().get(nextImport);
if (mapping == null) {
mapping = config.toModelImport(nextImport);
}
if (mapping != null) {
if (mapping != null && !mappingSet.contains(mapping)) { // ensure import (mapping) is unique
mappingSet.add(mapping);
im.put("import", mapping);
im.put("classname", nextImport);
if (!imports.contains(im)) { // avoid duplicates
@ -1053,6 +1076,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
if (imports.size() > 0) {
operations.put("hasImport", true);
}
config.postProcessOperations(operations);
config.postProcessOperationsWithModels(operations, allModels);
if (objs.size() > 0) {

View File

@ -160,21 +160,21 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
typeMapping = new HashMap<String, String>();
typeMapping.put("string", "string");
typeMapping.put("binary", "byte[]");
typeMapping.put("bytearray", "byte[]");
typeMapping.put("ByteArray", "byte[]");
typeMapping.put("boolean", "bool?");
typeMapping.put("integer", "int?");
typeMapping.put("float", "float?");
typeMapping.put("long", "long?");
typeMapping.put("double", "double?");
typeMapping.put("number", "decimal?");
typeMapping.put("datetime", "DateTime?");
typeMapping.put("DateTime", "DateTime?");
typeMapping.put("date", "DateTime?");
typeMapping.put("file", "System.IO.Stream");
typeMapping.put("array", "List");
typeMapping.put("list", "List");
typeMapping.put("map", "Dictionary");
typeMapping.put("object", "Object");
typeMapping.put("uuid", "Guid?");
typeMapping.put("UUID", "Guid?");
}
public void setReturnICollection(boolean returnICollection) {
@ -216,6 +216,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
if (StringUtils.isEmpty(System.getenv("CSHARP_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable CSHARP_POST_PROCESS_FILE not defined so the C# code may not be properly formatted by uncrustify (0.66 or later) or other code formatter. To define it, try `export CSHARP_POST_PROCESS_FILE=\"/usr/local/bin/uncrustify --no-backup\" && export UNCRUSTIFY_CONFIG=/path/to/uncrustify-rules.cfg` (Linux/Mac). Note: replace /path/to with the location of uncrustify-rules.cfg");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
// {{packageVersion}}
@ -766,20 +767,19 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
String type;
if (openAPIType == null) {
openAPIType = ""; // set swagger type to empty string if null
LOGGER.error("OpenAPI Type for {} is null. Default to UNKNOWN_OPENAPI_TYPE instead.", p.getName());
openAPIType = "UNKNOWN_OPENAPI_TYPE";
}
// NOTE: typeMapping here supports things like string/String, long/Long, datetime/DateTime as lowercase keys.
// Should we require explicit casing here (values are not insensitive).
// TODO avoid using toLowerCase as typeMapping should be case-sensitive
if (typeMapping.containsKey(openAPIType.toLowerCase(Locale.ROOT))) {
type = typeMapping.get(openAPIType.toLowerCase(Locale.ROOT));
if (typeMapping.containsKey(openAPIType)) {
type = typeMapping.get(openAPIType);
if (languageSpecificPrimitives.contains(type)) {
return type;
}
} else {
type = openAPIType;
}
return toModelName(type);
}

View File

@ -19,6 +19,8 @@ package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.ImmutableMap;
import com.samskivert.mustache.Mustache;
import org.openapitools.codegen.CodegenConfig;
@ -28,6 +30,7 @@ import org.openapitools.codegen.mustache.IndentedLambda;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.Arrays;
import java.util.Map;
@ -249,6 +252,12 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
public void processOpts() {
super.processOpts();
if (StringUtils.isEmpty(System.getenv("CPP_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable CPP_POST_PROCESS_FILE not defined so the C++ code may not be properly formatted. To define it, try 'export CPP_POST_PROCESS_FILE=\"/usr/local/bin/clang-format -i\"' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
addMustacheLambdas(additionalProperties);
}
@ -265,4 +274,31 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
objs.put("lambda", lambdas);
}
}
@Override
public void postProcessFile(File file, String fileType) {
if (file == null) {
return;
}
String cppPostProcessFile = System.getenv("CPP_POST_PROCESS_FILE");
if (StringUtils.isEmpty(cppPostProcessFile)) {
return; // skip if CPP_POST_PROCESS_FILE env variable is not defined
}
// only process files with cpp extension
if ("cpp".equals(FilenameUtils.getExtension(file.toString())) || "h".equals(FilenameUtils.getExtension(file.toString()))) {
String command = cppPostProcessFile + " " + file.toString();
try {
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
int exitValue = p.exitValue();
if (exitValue != 0) {
LOGGER.error("Error running the command ({}). Exit value: {}", command, exitValue);
} else {
LOGGER.info("Successfully executed: " + command);
}
} catch (Exception e) {
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
}
}
}
}

View File

@ -121,6 +121,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
if (StringUtils.isEmpty(System.getenv("GO_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable GO_POST_PROCESS_FILE not defined so Go code may not be properly formatted. To define it, try `export GO_POST_PROCESS_FILE=\"/usr/local/bin/gofmt -w\"` (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
}

View File

@ -215,6 +215,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
if (StringUtils.isEmpty(System.getenv("JAVA_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable JAVA_POST_PROCESS_FILE not defined so the Java code may not be properly formatted. To define it, try 'export JAVA_POST_PROCESS_FILE=\"/usr/local/bin/clang-format -i\"' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
if (additionalProperties.containsKey(SUPPORT_JAVA6)) {

View File

@ -45,6 +45,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/";
protected boolean parcelizeModels = false;
protected CodegenConstants.ENUM_PROPERTY_NAMING_TYPE enumPropertyNaming = CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.camelCase;
@ -199,6 +200,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
CliOption enumPropertyNamingOpt = new CliOption(CodegenConstants.ENUM_PROPERTY_NAMING, CodegenConstants.ENUM_PROPERTY_NAMING_DESC);
cliOptions.add(enumPropertyNamingOpt.defaultValue(enumPropertyNaming.name()));
cliOptions.add(new CliOption(CodegenConstants.PARCELIZE_MODELS, CodegenConstants.PARCELIZE_MODELS_DESC));
}
@Override
@ -356,6 +358,20 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
LOGGER.warn(CodegenConstants.INVOKER_PACKAGE + " with " + this.getName() + " generator is ignored. Use " + CodegenConstants.PACKAGE_NAME + ".");
}
if (additionalProperties.containsKey(CodegenConstants.PARCELIZE_MODELS)) {
this.setParcelizeModels(Boolean.valueOf((String)additionalProperties.get(CodegenConstants.PARCELIZE_MODELS)));
LOGGER.info(CodegenConstants.PARCELIZE_MODELS + " depends on the android framework and " +
"experimental parcelize feature. Make sure your build applies the android plugin:\n" +
"apply plugin: 'com.android.library' OR apply plugin: 'com.android.application'.\n" +
"and enables the experimental features:\n" +
"androidExtensions {\n" +
" experimental = true\n" +
"}"
);
} else {
additionalProperties.put(CodegenConstants.PARCELIZE_MODELS, parcelizeModels);
}
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage());
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage());
@ -383,6 +399,14 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
this.sourceFolder = sourceFolder;
}
public Boolean getParcelizeModels() {
return parcelizeModels;
}
public void setParcelizeModels(Boolean parcelizeModels) {
this.parcelizeModels = parcelizeModels;
}
/**
* Return the sanitized variable name for enum
*

View File

@ -18,6 +18,7 @@ package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConfig;
@ -40,12 +41,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractPhpCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPhpCodegen.class);
@ -161,6 +156,11 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
public void processOpts() {
super.processOpts();
if (StringUtils.isEmpty(System.getenv("PHP_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable PHP_POST_PROCESS_FILE not defined so the PHP code may not be properly formatted. To define it, try 'export PHP_POST_PROCESS_FILE=\"/usr/local/bin/prettier --write\"' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
if (additionalProperties.containsKey(PACKAGE_NAME)) {
this.setPackageName((String) additionalProperties.get(PACKAGE_NAME));
} else {
@ -773,4 +773,31 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
final int lastBackslashIndex = phpClassName.lastIndexOf('\\');
return phpClassName.substring(lastBackslashIndex + 1);
}
@Override
public void postProcessFile(File file, String fileType) {
if (file == null) {
return;
}
String phpPostProcessFile = System.getenv("PHP_POST_PROCESS_FILE");
if (StringUtils.isEmpty(phpPostProcessFile)) {
return; // skip if PHP_POST_PROCESS_FILE env variable is not defined
}
// only process files with php extension
if ("php".equals(FilenameUtils.getExtension(file.toString()))) {
String command = phpPostProcessFile + " " + file.toString();
try {
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
int exitValue = p.exitValue();
if (exitValue != 0) {
LOGGER.error("Error running the command ({}). Exit value: {}", command, exitValue);
} else {
LOGGER.info("Successfully executed: " + command);
}
} catch (Exception e) {
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
}
}
}
}

View File

@ -116,6 +116,7 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen {
if (StringUtils.isEmpty(System.getenv("SCALA_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable SCALA_POST_PROCESS_FILE not defined so the Scala code may not be properly formatted. To define it, try 'export SCALA_POST_PROCESS_FILE=/usr/local/bin/scalafmt' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {

View File

@ -0,0 +1,850 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright 2018 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.languages;
import static org.apache.commons.lang3.StringUtils.isEmpty;
import com.google.common.collect.ImmutableMap;
import com.samskivert.mustache.Mustache;
import io.swagger.v3.oas.models.media.Schema;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class CSharpRefactorClientCodegen extends AbstractCSharpCodegen {
@SuppressWarnings({"hiding"})
private static final Logger LOGGER = LoggerFactory.getLogger(CSharpClientCodegen.class);
private static final String NET45 = "v4.5";
private static final String NET40 = "v4.0";
private static final String NET35 = "v3.5";
// TODO: v5.0 is PCL, not netstandard version 1.3, and not a specific .NET Framework. This needs to be updated,
// especially because it will conflict with .NET Framework 5.0 when released, and PCL 5 refers to Framework 4.0.
// We should support either NETSTANDARD, PCL, or Both but the concepts shouldn't be mixed.
private static final String NETSTANDARD = "v5.0";
private static final String UWP = "uwp";
// Defines the sdk option for targeted frameworks, which differs from targetFramework and targetFrameworkNuget
private static final String MCS_NET_VERSION_KEY = "x-mcs-sdk";
protected String packageGuid = "{" + java.util.UUID.randomUUID().toString().toUpperCase(Locale.ROOT) + "}";
protected String clientPackage = "Org.OpenAPITools.Client";
protected String localVariablePrefix = "";
protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/";
// Defines TargetFrameworkVersion in csproj files
protected String targetFramework = NET45;
// Defines nuget identifiers for target framework
protected String targetFrameworkNuget = "net45";
protected boolean supportsAsync = Boolean.TRUE;
protected boolean supportsUWP = Boolean.FALSE;
protected boolean netStandard = Boolean.FALSE;
protected boolean generatePropertyChanged = Boolean.FALSE;
protected boolean validatable = Boolean.TRUE;
protected Map<Character, String> regexModifiers;
protected final Map<String, String> frameworks;
// By default, generated code is considered public
protected boolean nonPublicApi = Boolean.FALSE;
public CSharpRefactorClientCodegen() {
super();
supportsInheritance = true;
modelTemplateFiles.put("model.mustache", ".cs");
apiTemplateFiles.put("api.mustache", ".cs");
modelDocTemplateFiles.put("model_doc.mustache", ".md");
apiDocTemplateFiles.put("api_doc.mustache", ".md");
embeddedTemplateDir = templateDir = "csharp-refactor";
hideGenerationTimestamp = Boolean.TRUE;
cliOptions.clear();
// CLI options
addOption(CodegenConstants.PACKAGE_NAME,
"C# package name (convention: Title.Case).",
this.packageName);
addOption(CodegenConstants.PACKAGE_VERSION,
"C# package version.",
this.packageVersion);
addOption(CodegenConstants.SOURCE_FOLDER,
CodegenConstants.SOURCE_FOLDER_DESC,
sourceFolder);
addOption(CodegenConstants.OPTIONAL_PROJECT_GUID,
CodegenConstants.OPTIONAL_PROJECT_GUID_DESC,
null);
addOption(CodegenConstants.INTERFACE_PREFIX,
CodegenConstants.INTERFACE_PREFIX_DESC,
interfacePrefix);
CliOption framework = new CliOption(
CodegenConstants.DOTNET_FRAMEWORK,
CodegenConstants.DOTNET_FRAMEWORK_DESC
);
frameworks = new ImmutableMap.Builder<String, String>()
.put(NET35, ".NET Framework 3.5 compatible")
.put(NET40, ".NET Framework 4.0 compatible")
.put(NET45, ".NET Framework 4.5+ compatible")
.put(NETSTANDARD, ".NET Standard 1.3 compatible")
.put(UWP, "Universal Windows Platform (IMPORTANT: this will be decommissioned and replaced by v5.0)")
.build();
framework.defaultValue(this.targetFramework);
framework.setEnum(frameworks);
cliOptions.add(framework);
CliOption modelPropertyNaming = new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, CodegenConstants.MODEL_PROPERTY_NAMING_DESC);
cliOptions.add(modelPropertyNaming.defaultValue("PascalCase"));
// CLI Switches
addSwitch(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC,
this.hideGenerationTimestamp);
addSwitch(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG,
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC,
this.sortParamsByRequiredFlag);
addSwitch(CodegenConstants.USE_DATETIME_OFFSET,
CodegenConstants.USE_DATETIME_OFFSET_DESC,
this.useDateTimeOffsetFlag);
addSwitch(CodegenConstants.USE_COLLECTION,
CodegenConstants.USE_COLLECTION_DESC,
this.useCollection);
addSwitch(CodegenConstants.RETURN_ICOLLECTION,
CodegenConstants.RETURN_ICOLLECTION_DESC,
this.returnICollection);
addSwitch(CodegenConstants.OPTIONAL_METHOD_ARGUMENT,
"C# Optional method argument, e.g. void square(int x=10) (.net 4.0+ only).",
this.optionalMethodArgumentFlag);
addSwitch(CodegenConstants.OPTIONAL_ASSEMBLY_INFO,
CodegenConstants.OPTIONAL_ASSEMBLY_INFO_DESC,
this.optionalAssemblyInfoFlag);
addSwitch(CodegenConstants.OPTIONAL_PROJECT_FILE,
CodegenConstants.OPTIONAL_PROJECT_FILE_DESC,
this.optionalProjectFileFlag);
addSwitch(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES,
CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES_DESC,
this.optionalEmitDefaultValue);
addSwitch(CodegenConstants.GENERATE_PROPERTY_CHANGED,
CodegenConstants.PACKAGE_DESCRIPTION_DESC,
this.generatePropertyChanged);
// NOTE: This will reduce visibility of all public members in templates. Users can use InternalsVisibleTo
// https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute(v=vs.110).aspx
// to expose to shared code if the generated code is not embedded into another project. Otherwise, users of codegen
// should rely on default public visibility.
addSwitch(CodegenConstants.NON_PUBLIC_API,
CodegenConstants.NON_PUBLIC_API_DESC,
this.nonPublicApi);
addSwitch(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS,
CodegenConstants.ALLOW_UNICODE_IDENTIFIERS_DESC,
this.allowUnicodeIdentifiers);
addSwitch(CodegenConstants.NETCORE_PROJECT_FILE,
CodegenConstants.NETCORE_PROJECT_FILE_DESC,
this.netCoreProjectFileFlag);
addSwitch(CodegenConstants.VALIDATABLE,
CodegenConstants.VALIDATABLE_DESC,
this.validatable);
regexModifiers = new HashMap<Character, String>();
regexModifiers.put('i', "IgnoreCase");
regexModifiers.put('m', "Multiline");
regexModifiers.put('s', "Singleline");
regexModifiers.put('x', "IgnorePatternWhitespace");
}
@Override
public void processOpts() {
super.processOpts();
/*
* NOTE: When supporting boolean additionalProperties, you should read the value and write it back as a boolean.
* This avoids oddities where additionalProperties contains "false" rather than false, which will cause the
* templating engine to behave unexpectedly.
*
* Use the pattern:
* if (additionalProperties.containsKey(prop)) convertPropertyToBooleanAndWriteBack(prop);
*/
if (additionalProperties.containsKey(CodegenConstants.MODEL_PROPERTY_NAMING)) {
setModelPropertyNaming((String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING));
}
if (isEmpty(apiPackage)) {
setApiPackage("Api");
}
if (isEmpty(modelPackage)) {
setModelPackage("Model");
}
clientPackage = "Client";
Boolean excludeTests = false;
if (additionalProperties.containsKey(CodegenConstants.EXCLUDE_TESTS)) {
excludeTests = convertPropertyToBooleanAndWriteBack(CodegenConstants.EXCLUDE_TESTS);
}
if (additionalProperties.containsKey(CodegenConstants.VALIDATABLE)) {
setValidatable(convertPropertyToBooleanAndWriteBack(CodegenConstants.VALIDATABLE));
} else {
additionalProperties.put(CodegenConstants.VALIDATABLE, validatable);
}
if (additionalProperties.containsKey(CodegenConstants.DOTNET_FRAMEWORK)) {
setTargetFramework((String) additionalProperties.get(CodegenConstants.DOTNET_FRAMEWORK));
} else {
// Ensure default is set.
setTargetFramework(NET45);
additionalProperties.put(CodegenConstants.DOTNET_FRAMEWORK, this.targetFramework);
}
if (NET35.equals(this.targetFramework)) {
// This is correct, mono will require you build .NET 3.5 sources using 4.0 SDK
additionalProperties.put(MCS_NET_VERSION_KEY, "4");
additionalProperties.put("net35", true);
if (additionalProperties.containsKey(CodegenConstants.SUPPORTS_ASYNC)) {
LOGGER.warn(".NET 3.5 generator does not support async.");
additionalProperties.remove(CodegenConstants.SUPPORTS_ASYNC);
}
setTargetFrameworkNuget("net35");
setValidatable(Boolean.FALSE);
setSupportsAsync(Boolean.FALSE);
} else if (NETSTANDARD.equals(this.targetFramework)) {
// TODO: NETSTANDARD here is misrepresenting a PCL v5.0 which supports .NET Framework 4.6+, .NET Core 1.0, and Windows Universal 10.0
additionalProperties.put(MCS_NET_VERSION_KEY, "4.6-api");
if (additionalProperties.containsKey("supportsUWP")) {
LOGGER.warn(".NET " + NETSTANDARD + " generator does not support UWP.");
additionalProperties.remove("supportsUWP");
}
// TODO: NETSTANDARD=v5.0 and targetFrameworkNuget=netstandard1.3. These need to sync.
setTargetFrameworkNuget("netstandard1.3");
setSupportsAsync(Boolean.TRUE);
setSupportsUWP(Boolean.FALSE);
setNetStandard(Boolean.TRUE);
//Tests not yet implemented for .NET Standard codegen
//Todo implement it
excludeTests = true;
} else if (UWP.equals(this.targetFramework)) {
setTargetFrameworkNuget("uwp");
setSupportsAsync(Boolean.TRUE);
setSupportsUWP(Boolean.TRUE);
} else if (NET40.equals(this.targetFramework)) {
additionalProperties.put(MCS_NET_VERSION_KEY, "4");
additionalProperties.put("isNet40", true);
if (additionalProperties.containsKey(CodegenConstants.SUPPORTS_ASYNC)) {
LOGGER.warn(".NET " + NET40 + " generator does not support async.");
additionalProperties.remove(CodegenConstants.SUPPORTS_ASYNC);
}
setTargetFrameworkNuget("net40");
setSupportsAsync(Boolean.FALSE);
} else {
additionalProperties.put(MCS_NET_VERSION_KEY, "4.5.2-api");
setTargetFrameworkNuget("net45");
setSupportsAsync(Boolean.TRUE);
}
if (additionalProperties.containsKey(CodegenConstants.GENERATE_PROPERTY_CHANGED)) {
if (NET35.equals(targetFramework)) {
LOGGER.warn(CodegenConstants.GENERATE_PROPERTY_CHANGED + " is only supported by generated code for .NET 4+.");
additionalProperties.remove(CodegenConstants.GENERATE_PROPERTY_CHANGED);
} else if (NETSTANDARD.equals(targetFramework)) {
LOGGER.warn(CodegenConstants.GENERATE_PROPERTY_CHANGED + " is not supported in .NET Standard generated code.");
additionalProperties.remove(CodegenConstants.GENERATE_PROPERTY_CHANGED);
} else if (Boolean.TRUE.equals(netCoreProjectFileFlag)) {
LOGGER.warn(CodegenConstants.GENERATE_PROPERTY_CHANGED + " is not supported in .NET Core csproj project format.");
additionalProperties.remove(CodegenConstants.GENERATE_PROPERTY_CHANGED);
} else {
setGeneratePropertyChanged(convertPropertyToBooleanAndWriteBack(CodegenConstants.GENERATE_PROPERTY_CHANGED));
}
}
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
additionalProperties.put("clientPackage", clientPackage);
additionalProperties.put(CodegenConstants.EXCLUDE_TESTS, excludeTests);
additionalProperties.put(CodegenConstants.VALIDATABLE, this.validatable);
additionalProperties.put(CodegenConstants.SUPPORTS_ASYNC, this.supportsAsync);
additionalProperties.put("supportsUWP", this.supportsUWP);
additionalProperties.put("netStandard", this.netStandard);
additionalProperties.put("targetFrameworkNuget", this.targetFrameworkNuget);
// TODO: either remove this and update templates to match the "optionalEmitDefaultValues" property, or rename that property.
additionalProperties.put("emitDefaultValue", optionalEmitDefaultValue);
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_PROJECT_FILE)) {
setOptionalProjectFileFlag(convertPropertyToBooleanAndWriteBack(CodegenConstants.OPTIONAL_PROJECT_FILE));
} else {
additionalProperties.put(CodegenConstants.OPTIONAL_PROJECT_FILE, optionalProjectFileFlag);
}
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_PROJECT_GUID)) {
setPackageGuid((String) additionalProperties.get(CodegenConstants.OPTIONAL_PROJECT_GUID));
} else {
additionalProperties.put(CodegenConstants.OPTIONAL_PROJECT_GUID, packageGuid);
}
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_METHOD_ARGUMENT)) {
setOptionalMethodArgumentFlag(convertPropertyToBooleanAndWriteBack(CodegenConstants.OPTIONAL_METHOD_ARGUMENT));
} else {
additionalProperties.put(CodegenConstants.OPTIONAL_METHOD_ARGUMENT, optionalMethodArgumentFlag);
}
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_ASSEMBLY_INFO)) {
setOptionalAssemblyInfoFlag(convertPropertyToBooleanAndWriteBack(CodegenConstants.OPTIONAL_ASSEMBLY_INFO));
} else {
additionalProperties.put(CodegenConstants.OPTIONAL_ASSEMBLY_INFO, optionalAssemblyInfoFlag);
}
if (additionalProperties.containsKey(CodegenConstants.NON_PUBLIC_API)) {
setNonPublicApi(convertPropertyToBooleanAndWriteBack(CodegenConstants.NON_PUBLIC_API));
} else {
additionalProperties.put(CodegenConstants.NON_PUBLIC_API, isNonPublicApi());
}
final String testPackageName = testPackageName();
String packageFolder = sourceFolder + File.separator + packageName;
String clientPackageDir = packageFolder + File.separator + clientPackage;
String testPackageFolder = testFolder + File.separator + testPackageName;
additionalProperties.put("testPackageName", testPackageName);
//Compute the relative path to the bin directory where the external assemblies live
//This is necessary to properly generate the project file
int packageDepth = packageFolder.length() - packageFolder.replace(java.io.File.separator, "").length();
String binRelativePath = "..\\";
for (int i = 0; i < packageDepth; i = i + 1)
binRelativePath += "..\\";
binRelativePath += "vendor";
additionalProperties.put("binRelativePath", binRelativePath);
supportingFiles.add(new SupportingFile("IApiAccessor.mustache",
clientPackageDir, "IApiAccessor.cs"));
supportingFiles.add(new SupportingFile("Configuration.mustache",
clientPackageDir, "Configuration.cs"));
supportingFiles.add(new SupportingFile("ApiClient.mustache",
clientPackageDir, "ApiClient.cs"));
supportingFiles.add(new SupportingFile("ApiException.mustache",
clientPackageDir, "ApiException.cs"));
supportingFiles.add(new SupportingFile("ApiResponse.mustache",
clientPackageDir, "ApiResponse.cs"));
supportingFiles.add(new SupportingFile("ExceptionFactory.mustache",
clientPackageDir, "ExceptionFactory.cs"));
supportingFiles.add(new SupportingFile("OpenAPIDateConverter.mustache",
clientPackageDir, "OpenAPIDateConverter.cs"));
supportingFiles.add(new SupportingFile("ClientUtils.mustache",
clientPackageDir, "ClientUtils.cs"));
supportingFiles.add(new SupportingFile("HttpMethod.mustache",
clientPackageDir, "HttpMethod.cs"));
supportingFiles.add(new SupportingFile("IAsynchronousClient.mustache",
clientPackageDir, "IAsynchronousClient.cs"));
supportingFiles.add(new SupportingFile("ISynchronousClient.mustache",
clientPackageDir, "ISynchronousClient.cs"));
supportingFiles.add(new SupportingFile("RequestOptions.mustache",
clientPackageDir, "RequestOptions.cs"));
supportingFiles.add(new SupportingFile("Multimap.mustache",
clientPackageDir, "Multimap.cs"));
if (Boolean.FALSE.equals(this.netStandard) && Boolean.FALSE.equals(this.netCoreProjectFileFlag)) {
supportingFiles.add(new SupportingFile("compile.mustache", "", "build.bat"));
supportingFiles.add(new SupportingFile("compile-mono.sh.mustache", "", "build.sh"));
// copy package.config to nuget's standard location for project-level installs
supportingFiles.add(new SupportingFile("packages.config.mustache", packageFolder + File.separator, "packages.config"));
// .travis.yml for travis-ci.org CI
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
} else if (Boolean.FALSE.equals(this.netCoreProjectFileFlag)) {
supportingFiles.add(new SupportingFile("project.json.mustache", packageFolder + File.separator, "project.json"));
}
supportingFiles.add(new SupportingFile("IReadableConfiguration.mustache",
clientPackageDir, "IReadableConfiguration.cs"));
supportingFiles.add(new SupportingFile("GlobalConfiguration.mustache",
clientPackageDir, "GlobalConfiguration.cs"));
// Only write out test related files if excludeTests is unset or explicitly set to false (see start of this method)
if (Boolean.FALSE.equals(excludeTests)) {
// shell script to run the nunit test
supportingFiles.add(new SupportingFile("mono_nunit_test.mustache", "", "mono_nunit_test.sh"));
modelTestTemplateFiles.put("model_test.mustache", ".cs");
apiTestTemplateFiles.put("api_test.mustache", ".cs");
if (Boolean.FALSE.equals(this.netCoreProjectFileFlag)) {
supportingFiles.add(new SupportingFile("packages_test.config.mustache", testPackageFolder + File.separator, "packages.config"));
}
if (NET40.equals(this.targetFramework)) {
// Include minimal tests for modifications made to JsonSubTypes, since code is quite different for .net 4.0 from original implementation
supportingFiles.add(new SupportingFile("JsonSubTypesTests.mustache",
testPackageFolder + File.separator + "Client",
"JsonSubTypesTests.cs"));
}
}
if (Boolean.TRUE.equals(generatePropertyChanged)) {
supportingFiles.add(new SupportingFile("FodyWeavers.xml", packageFolder, "FodyWeavers.xml"));
}
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
if (optionalAssemblyInfoFlag && Boolean.FALSE.equals(this.netCoreProjectFileFlag)) {
supportingFiles.add(new SupportingFile("AssemblyInfo.mustache", packageFolder + File.separator + "Properties", "AssemblyInfo.cs"));
}
if (optionalProjectFileFlag) {
supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln"));
if (Boolean.TRUE.equals(this.netCoreProjectFileFlag)) {
supportingFiles.add(new SupportingFile("netcore_project.mustache", packageFolder, packageName + ".csproj"));
} else {
supportingFiles.add(new SupportingFile("Project.mustache", packageFolder, packageName + ".csproj"));
if (Boolean.FALSE.equals(this.netStandard)) {
supportingFiles.add(new SupportingFile("nuspec.mustache", packageFolder, packageName + ".nuspec"));
}
}
if (Boolean.FALSE.equals(excludeTests)) {
// NOTE: This exists here rather than previous excludeTests block because the test project is considered an optional project file.
if (Boolean.TRUE.equals(this.netCoreProjectFileFlag)) {
supportingFiles.add(new SupportingFile("netcore_testproject.mustache", testPackageFolder, testPackageName + ".csproj"));
} else {
supportingFiles.add(new SupportingFile("TestProject.mustache", testPackageFolder, testPackageName + ".csproj"));
}
}
}
additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath);
}
public void setModelPropertyNaming(String naming) {
if ("original".equals(naming) || "camelCase".equals(naming) ||
"PascalCase".equals(naming) || "snake_case".equals(naming)) {
this.modelPropertyNaming = naming;
} else {
throw new IllegalArgumentException("Invalid model property naming '" +
naming + "'. Must be 'original', 'camelCase', " +
"'PascalCase' or 'snake_case'");
}
}
public String getModelPropertyNaming() {
return this.modelPropertyNaming;
}
@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
super.postProcessOperationsWithModels(objs, allModels);
if (objs != null) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
if (operation.returnType != null) {
operation.returnContainer = operation.returnType;
if (this.returnICollection && (
operation.returnType.startsWith("List") ||
operation.returnType.startsWith("Collection"))) {
// NOTE: ICollection works for both List<T> and Collection<T>
int genericStart = operation.returnType.indexOf("<");
if (genericStart > 0) {
operation.returnType = "ICollection" + operation.returnType.substring(genericStart);
}
}
}
}
}
}
return objs;
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getName() {
return "csharp-refactor";
}
@Override
public String getHelp() {
return "Generates a CSharp client library.";
}
public void setOptionalAssemblyInfoFlag(boolean flag) {
this.optionalAssemblyInfoFlag = flag;
}
@Override
public CodegenModel fromModel(String name, Schema model, Map<String, Schema> allDefinitions) {
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
if (allDefinitions != null && codegenModel != null && codegenModel.parent != null) {
final Schema parentModel = allDefinitions.get(toModelName(codegenModel.parent));
if (parentModel != null) {
final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel, allDefinitions);
if (codegenModel.hasEnums) {
codegenModel = this.reconcileInlineEnums(codegenModel, parentCodegenModel);
}
Map<String, CodegenProperty> propertyHash = new HashMap<>(codegenModel.vars.size());
for (final CodegenProperty property : codegenModel.vars) {
propertyHash.put(property.name, property);
}
for (final CodegenProperty property : codegenModel.readWriteVars) {
if (property.defaultValue == null && property.baseName.equals(parentCodegenModel.discriminator)) {
property.defaultValue = "\"" + name + "\"";
}
}
CodegenProperty last = null;
for (final CodegenProperty property : parentCodegenModel.vars) {
// helper list of parentVars simplifies templating
if (!propertyHash.containsKey(property.name)) {
final CodegenProperty parentVar = property.clone();
parentVar.isInherited = true;
parentVar.hasMore = true;
last = parentVar;
LOGGER.info("adding parent variable {}", property.name);
codegenModel.parentVars.add(parentVar);
}
}
if (last != null) {
last.hasMore = false;
}
}
}
// Cleanup possible duplicates. Currently, readWriteVars can contain the same property twice. May or may not be isolated to C#.
if (codegenModel != null && codegenModel.readWriteVars != null && codegenModel.readWriteVars.size() > 1) {
int length = codegenModel.readWriteVars.size() - 1;
for (int i = length; i > (length / 2); i--) {
final CodegenProperty codegenProperty = codegenModel.readWriteVars.get(i);
// If the property at current index is found earlier in the list, remove this last instance.
if (codegenModel.readWriteVars.indexOf(codegenProperty) < i) {
codegenModel.readWriteVars.remove(i);
}
}
}
return codegenModel;
}
public void setOptionalProjectFileFlag(boolean flag) {
this.optionalProjectFileFlag = flag;
}
public void setPackageGuid(String packageGuid) {
this.packageGuid = packageGuid;
}
@Override
public void postProcessParameter(CodegenParameter parameter) {
postProcessPattern(parameter.pattern, parameter.vendorExtensions);
super.postProcessParameter(parameter);
}
@Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
postProcessPattern(property.pattern, property.vendorExtensions);
super.postProcessModelProperty(model, property);
}
/*
* The pattern spec follows the Perl convention and style of modifiers. .NET
* does not support this syntax directly so we need to convert the pattern to a .NET compatible
* format and apply modifiers in a compatible way.
* See https://msdn.microsoft.com/en-us/library/yd1hzczs(v=vs.110).aspx for .NET options.
*/
public void postProcessPattern(String pattern, Map<String, Object> vendorExtensions) {
if (pattern != null) {
int i = pattern.lastIndexOf('/');
//Must follow Perl /pattern/modifiers convention
if (pattern.charAt(0) != '/' || i < 2) {
throw new IllegalArgumentException("Pattern must follow the Perl "
+ "/pattern/modifiers convention. " + pattern + " is not valid.");
}
String regex = pattern.substring(1, i).replace("'", "\'");
List<String> modifiers = new ArrayList<String>();
// perl requires an explicit modifier to be culture specific and .NET is the reverse.
modifiers.add("CultureInvariant");
for (char c : pattern.substring(i).toCharArray()) {
if (regexModifiers.containsKey(c)) {
String modifier = regexModifiers.get(c);
modifiers.add(modifier);
} else if (c == 'l') {
modifiers.remove("CultureInvariant");
}
}
vendorExtensions.put("x-regex", regex);
vendorExtensions.put("x-modifiers", modifiers);
}
}
public void setTargetFramework(String dotnetFramework) {
if (!frameworks.containsKey(dotnetFramework)) {
LOGGER.warn("Invalid .NET framework version, defaulting to " + this.targetFramework);
} else {
this.targetFramework = dotnetFramework;
}
LOGGER.info("Generating code for .NET Framework " + this.targetFramework);
}
private CodegenModel reconcileInlineEnums(CodegenModel codegenModel, CodegenModel parentCodegenModel) {
// This generator uses inline classes to define enums, which breaks when
// dealing with models that have subTypes. To clean this up, we will analyze
// the parent and child models, look for enums that match, and remove
// them from the child models and leave them in the parent.
// Because the child models extend the parents, the enums will be available via the parent.
// Only bother with reconciliation if the parent model has enums.
if (parentCodegenModel.hasEnums) {
// Get the properties for the parent and child models
final List<CodegenProperty> parentModelCodegenProperties = parentCodegenModel.vars;
List<CodegenProperty> codegenProperties = codegenModel.vars;
// Iterate over all of the parent model properties
boolean removedChildEnum = false;
for (CodegenProperty parentModelCodegenPropery : parentModelCodegenProperties) {
// Look for enums
if (parentModelCodegenPropery.isEnum) {
// Now that we have found an enum in the parent class,
// and search the child class for the same enum.
Iterator<CodegenProperty> iterator = codegenProperties.iterator();
while (iterator.hasNext()) {
CodegenProperty codegenProperty = iterator.next();
if (codegenProperty.isEnum && codegenProperty.equals(parentModelCodegenPropery)) {
// We found an enum in the child class that is
// a duplicate of the one in the parent, so remove it.
iterator.remove();
removedChildEnum = true;
}
}
}
}
if (removedChildEnum) {
// If we removed an entry from this model's vars, we need to ensure hasMore is updated
int count = 0, numVars = codegenProperties.size();
for (CodegenProperty codegenProperty : codegenProperties) {
count += 1;
codegenProperty.hasMore = count < numVars;
}
codegenModel.vars = codegenProperties;
}
}
return codegenModel;
}
@Override
public String toEnumVarName(String value, String datatype) {
if (value.length() == 0) {
return "Empty";
}
// for symbol, e.g. $, #
if (getSymbolName(value) != null) {
return camelize(getSymbolName(value));
}
// number
if (datatype.startsWith("int") || datatype.startsWith("long") ||
datatype.startsWith("double") || datatype.startsWith("float")) {
String varName = "NUMBER_" + value;
varName = varName.replaceAll("-", "MINUS_");
varName = varName.replaceAll("\\+", "PLUS_");
varName = varName.replaceAll("\\.", "_DOT_");
return varName;
}
// string
String var = value.replaceAll("_", " ");
//var = WordUtils.capitalizeFully(var);
var = camelize(var);
var = var.replaceAll("\\W+", "");
if (var.matches("\\d.*")) {
return "_" + var;
} else {
return var;
}
}
@Override
public String toVarName(String name) {
// sanitize name
name = sanitizeName(name);
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$")) {
return name;
}
name = getNameUsingModelPropertyNaming(name);
// for reserved word or word starting with number, append _
if (isReservedWord(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
return name;
}
public String getNameUsingModelPropertyNaming(String name) {
switch (CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.valueOf(getModelPropertyNaming())) {
case original:
return name;
case camelCase:
return camelize(name, true);
case PascalCase:
return camelize(name);
case snake_case:
return underscore(name);
default:
throw new IllegalArgumentException("Invalid model property naming '" +
name + "'. Must be 'original', 'camelCase', " +
"'PascalCase' or 'snake_case'");
}
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
public void setTargetFrameworkNuget(String targetFrameworkNuget) {
this.targetFrameworkNuget = targetFrameworkNuget;
}
public void setSupportsAsync(Boolean supportsAsync) {
this.supportsAsync = supportsAsync;
}
public void setSupportsUWP(Boolean supportsUWP) {
this.supportsUWP = supportsUWP;
}
public void setNetStandard(Boolean netStandard) {
this.netStandard = netStandard;
}
public void setGeneratePropertyChanged(final Boolean generatePropertyChanged) {
this.generatePropertyChanged = generatePropertyChanged;
}
public boolean isNonPublicApi() {
return nonPublicApi;
}
public void setNonPublicApi(final boolean nonPublicApi) {
this.nonPublicApi = nonPublicApi;
}
public void setValidatable(boolean validatable) {
this.validatable = validatable;
}
@Override
public String toModelDocFilename(String name) {
return toModelFilename(name);
}
@Override
public String apiDocFileFolder() {
return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar);
}
@Override
public String modelDocFileFolder() {
return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar);
}
@Override
public String apiTestFileFolder() {
return outputFolder + File.separator + testFolder + File.separator + testPackageName() + File.separator + apiPackage();
}
@Override
public String modelTestFileFolder() {
return outputFolder + File.separator + testFolder + File.separator + testPackageName() + File.separator + modelPackage();
}
@Override
public Mustache.Compiler processCompiler(Mustache.Compiler compiler) {
// To avoid unexpected behaviors when options are passed programmatically such as { "supportsAsync": "" }
return super.processCompiler(compiler).emptyStringIsFalse(true);
}
}

View File

@ -160,7 +160,7 @@ public class CppQt5ClientCodegen extends CppQt5AbstractCodegen implements Codege
@Override
public String toApiFilename(String name) {
return modelNamePrefix + initialCaps(name) + "Api";
return modelNamePrefix + sanitizeName(initialCaps(name)) + "Api";
}
public void setOptionalProjectFileFlag(boolean flag) {

View File

@ -152,6 +152,7 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
if (StringUtils.isEmpty(System.getenv("DART_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable DART_POST_PROCESS_FILE not defined so the Dart code may not be properly formatted. To define it, try `export DART_POST_PROCESS_FILE=\"/usr/local/bin/dartfmt -w\"` (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
if (additionalProperties.containsKey(BROWSER_CLIENT)) {

View File

@ -191,6 +191,7 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
} else { // 0.19
LOGGER.info("Environment variable ELM_POST_PROCESS_FILE not defined so the Elm code may not be properly formatted. To define it, try `export ELM_POST_PROCESS_FILE=\"/usr/local/bin/elm-format --elm-version={} --yes\"` (Linux/Mac)", "0.19");
}
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
switch (elmVersion) {
@ -261,7 +262,13 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toEnumVarName(String value, String datatype) {
final String camelized = org.openapitools.codegen.utils.StringUtils.camelize(value.replace(" ", "_").replace("(", "_").replace(")", "")); // TODO FIXME escape properly
String camelized = org.openapitools.codegen.utils.StringUtils.camelize(value.replace(" ", "_").replace("(", "_").replace(")", "")); // TODO FIXME escape properly
if (camelized.length() == 0) {
LOGGER.error("Unable to determine enum variable name (name: {}, datatype: {}) from empty string. Default to UnknownEnumVariableName", value, datatype);
camelized = "UnknownEnumVariableName";
}
if (!Character.isUpperCase(camelized.charAt(0))) {
return "N" + camelized;
}
@ -495,9 +502,8 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
} else if (ModelUtils.isDateTimeSchema(p)) {
return toOptionalValue(null);
} else if (ModelUtils.isNumberSchema(p)) {
NumberSchema dp = (NumberSchema) p;
if (dp.getDefault() != null) {
return toOptionalValue(dp.getDefault().toString());
if (p.getDefault() != null) {
return toOptionalValue(p.getDefault().toString());
}
return toOptionalValue(null);
} else if (ModelUtils.isIntegerSchema(p)) {

View File

@ -152,6 +152,7 @@ public class JavaResteasyServerCodegen extends AbstractJavaJAXRSServerCodegen im
@Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
super.postProcessModelProperty(model, property);
//Add imports for Jackson
if (!BooleanUtils.toBoolean(model.isEnum)) {
model.imports.add("JsonProperty");

View File

@ -234,6 +234,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
if (StringUtils.isEmpty(System.getenv("JS_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable JS_POST_PROCESS_FILE not defined so the JS code may not be properly formatted. To define it, try 'export JS_POST_PROCESS_FILE=\"/usr/local/bin/js-beautify -r -f\"' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
if (additionalProperties.containsKey(PROJECT_NAME)) {

View File

@ -135,6 +135,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
if (StringUtils.isEmpty(System.getenv("PERL_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable PERL_POST_PROCESS_FILE not defined so the Perl code may not be properly formatted. To define it, try 'export PERL_POST_PROCESS_FILE=/usr/local/bin/perltidy -b -bext=\"/\"' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
if (additionalProperties.containsKey(MODULE_VERSION)) {

View File

@ -174,6 +174,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
if (StringUtils.isEmpty(System.getenv("PYTHON_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable PYTHON_POST_PROCESS_FILE not defined so the Python code may not be properly formatted. To define it, try 'export PYTHON_POST_PROCESS_FILE=\"/usr/local/bin/yapf -i\"' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
Boolean excludeTests = false;

View File

@ -157,6 +157,7 @@ public class PythonFlaskConnexionServerCodegen extends DefaultCodegen implements
if (StringUtils.isEmpty(System.getenv("PYTHON_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable PYTHON_POST_PROCESS_FILE not defined so the Python code may not be properly formatted. To define it, try 'export PYTHON_POST_PROCESS_FILE=\"/usr/local/bin/yapf -i\"' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
//apiTemplateFiles.clear();

View File

@ -245,6 +245,7 @@ public class Swift3Codegen extends DefaultCodegen implements CodegenConfig {
if (StringUtils.isEmpty(System.getenv("SWIFT_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable SWIFT_POST_PROCESS_FILE not defined so the Swift code may not be properly formatted. To define it, try 'export SWIFT_POST_PROCESS_FILE=/usr/local/bin/swiftformat' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
// Setup project name

View File

@ -300,6 +300,7 @@ public class Swift4Codegen extends DefaultCodegen implements CodegenConfig {
if (StringUtils.isEmpty(System.getenv("SWIFT_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable SWIFT_POST_PROCESS_FILE not defined so the Swift code may not be properly formatted. To define it, try 'export SWIFT_POST_PROCESS_FILE=/usr/local/bin/swiftformat' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
// Setup project name

View File

@ -25,7 +25,9 @@ import org.threeten.bp.OffsetDateTime;
import org.threeten.bp.format.DateTimeFormatter;
{{/threetenbp}}
{{#models.0}}
import {{modelPackage}}.*;
{{/models.0}}
import okio.ByteString;
import java.io.IOException;

View File

@ -25,7 +25,9 @@ import org.threeten.bp.OffsetDateTime;
import org.threeten.bp.format.DateTimeFormatter;
{{/threetenbp}}
{{#models.0}}
import {{modelPackage}}.*;
{{/models.0}}
import java.io.IOException;
import java.io.StringReader;

View File

@ -0,0 +1 @@
{{#allowableValues}}allowableValues="{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}{{^values}}range=[{{#min}}{{.}}{{/min}}{{^min}}-infinity{{/min}}, {{#max}}{{.}}{{/max}}{{^max}}infinity{{/max}}]{{/values}}"{{/allowableValues}}

View File

@ -14,6 +14,7 @@ org.openapitools.codegen.languages.CppRestbedServerCodegen
org.openapitools.codegen.languages.CppRestSdkClientCodegen
org.openapitools.codegen.languages.CppTizenClientCodegen
org.openapitools.codegen.languages.CSharpClientCodegen
org.openapitools.codegen.languages.CSharpRefactorClientCodegen
org.openapitools.codegen.languages.CSharpDotNet2ClientCodegen
org.openapitools.codegen.languages.CSharpNancyFXServerCodegen
org.openapitools.codegen.languages.DartClientCodegen

View File

@ -5,7 +5,9 @@ import {{invokerPackage}}.ApiException;
import {{invokerPackage}}.ApiInvoker;
import {{invokerPackage}}.Pair;
{{#hasModel}}
import {{modelPackage}}.*;
{{/hasModel}}
import java.util.*;

View File

@ -5,7 +5,9 @@ import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
{{#hasModel}}
import {{modelPackage}}.*;
{{/hasModel}}
public class JsonUtil {
public static GsonBuilder gsonBuilder;

View File

@ -5,7 +5,9 @@ import {{invokerPackage}}.ApiInvoker;
import {{invokerPackage}}.ApiException;
import {{invokerPackage}}.Pair;
{{#hasModel}}
import {{modelPackage}}.*;
{{/hasModel}}
import java.util.*;

View File

@ -11,7 +11,9 @@ import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Date;
{{#models.0}}
import {{modelPackage}}.*;
{{/models.0}}
public class JsonUtil {
public static GsonBuilder gsonBuilder;

View File

@ -0,0 +1,555 @@
{{>partial_header}}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.IO;
{{^netStandard}}
{{^supportsUWP}}
using System.Web;
{{/supportsUWP}}
{{/netStandard}}
using System.Linq;
using System.Net;
using System.Text;
using Newtonsoft.Json;
{{#netStandard}}
using RestSharp.Portable;
using RestSharp.Portable.HttpClient;
using RestSharpMethod = RestSharp.Portable.Method;
{{/netStandard}}
{{^netStandard}}
using RestSharp;
using RestSharpMethod = RestSharp.Method;
{{/netStandard}}
namespace {{packageName}}.Client
{
/// <summary>
/// Allows RestSharp to Serialize/Deserialize JSON using our custom logic, but only when ContentType is JSON.
/// </summary>
internal class CustomJsonCodec : RestSharp.Serializers.ISerializer, RestSharp.Deserializers.IDeserializer
{
private readonly IReadableConfiguration _configuration;
private readonly JsonSerializer _serializer;
private string _contentType = "application/json";
private readonly JsonSerializerSettings _serializerSettings = new JsonSerializerSettings
{
// Swagger generated types generally hide default constructors.
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
};
public CustomJsonCodec(IReadableConfiguration configuration)
{
_configuration = configuration;
_serializer = JsonSerializer.Create(_serializerSettings);
}
public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfiguration configuration)
{
_serializerSettings = serializerSettings;
_serializer = JsonSerializer.Create(_serializerSettings);
_configuration = configuration;
}
public string Serialize(object obj)
{
using (var writer = new StringWriter())
using (var jsonWriter = new JsonTextWriter(writer)
{
Formatting = Formatting.None,
DateFormatString = _configuration.DateTimeFormat
})
{
_serializer.Serialize(jsonWriter, obj);
return writer.ToString();
}
}
public T Deserialize<T>(IRestResponse response)
{
return (T) Deserialize(response, typeof(T));
}
/// <summary>
/// Deserialize the JSON string into a proper object.
/// </summary>
/// <param name="response">The HTTP response.</param>
/// <param name="type">Object type.</param>
/// <returns>Object representation of the JSON string.</returns>
internal object Deserialize(IRestResponse response, Type type)
{
IList<Parameter> headers = response.Headers;
if (type == typeof(byte[])) // return byte array
{
return response.RawBytes;
}
// TODO: ? if (type.IsAssignableFrom(typeof(Stream)))
if (type == typeof(Stream))
{
if (headers != null)
{
var filePath = String.IsNullOrEmpty(_configuration.TempFolderPath)
? Path.GetTempPath()
: _configuration.TempFolderPath;
var regex = new Regex(@"Content-Disposition=.*filename=['""]?([^'""\s]+)['""]?$");
foreach (var header in headers)
{
var match = regex.Match(header.ToString());
if (match.Success)
{
string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", ""));
File.WriteAllBytes(fileName, response.RawBytes);
return new FileStream(fileName, FileMode.Open);
}
}
}
var stream = new MemoryStream(response.RawBytes);
return stream;
}
if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object
{
return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind);
}
if (type == typeof(String) || type.Name.StartsWith("System.Nullable")) // return primitive type
{
return ClientUtils.ConvertType(response.Content, type);
}
// at this point, it must be a model (json)
try
{
return JsonConvert.DeserializeObject(response.Content, type, _serializerSettings);
}
catch (Exception e)
{
throw new ApiException(500, e.Message);
}
}
public string RootElement { get; set; }
public string Namespace { get; set; }
public string DateFormat { get; set; }
public string ContentType
{
get { return _contentType; }
set { throw new InvalidOperationException("Not allowed to set content type."); }
}
}
{{! NOTE: Any changes related to RestSharp should be done in this class. All other client classes are for extensibility by consumers.}}
/// <summary>
/// Provides a default implementation of an Api client (both synchronous and asynchronous implementatios),
/// encapsulating general REST accessor use cases.
/// </summary>
{{>visibility}} partial class ApiClient : ISynchronousClient{{#supportsAsync}}, IAsynchronousClient{{/supportsAsync}}
{
private readonly String _baseUrl;
/// <summary>
/// Allows for extending request processing for <see cref="ApiClient"/> generated code.
/// </summary>
/// <param name="request">The RestSharp request object</param>
partial void InterceptRequest(IRestRequest request);
/// <summary>
/// Allows for extending response processing for <see cref="ApiClient"/> generated code.
/// </summary>
/// <param name="request">The RestSharp request object</param>
/// <param name="response">The RestSharp response object</param>
partial void InterceptResponse(IRestRequest request, IRestResponse response);
/// <summary>
/// Initializes a new instance of the <see cref="ApiClient" />, defaulting to the global configurations' base url.
/// </summary>
public ApiClient()
{
_baseUrl = {{packageName}}.Client.GlobalConfiguration.Instance.BasePath;
}
/// <summary>
/// Initializes a new instance of the <see cref="ApiClient" />
/// </summary>
/// <param name="baseUrl">The target service's base path in URL format.</param>
/// <exception cref="ArgumentException"></exception>
public ApiClient(String basePath)
{
if (String.IsNullOrEmpty(basePath))
throw new ArgumentException("basePath cannot be empty");
_baseUrl = basePath;
}
/// <summary>
/// Constructs the RestSharp version of an http method
/// </summary>
/// <param name="method">Swagger Client Custom HttpMethod</param>
/// <returns>RestSharp's HttpMethod instance.</returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
private RestSharpMethod Method(HttpMethod method)
{
RestSharpMethod other;
switch (method)
{
case HttpMethod.Get:
other = RestSharpMethod.GET;
break;
case HttpMethod.Post:
other = RestSharpMethod.POST;
break;
case HttpMethod.Put:
other = RestSharpMethod.PUT;
break;
case HttpMethod.Delete:
other = RestSharpMethod.DELETE;
break;
case HttpMethod.Head:
other = RestSharpMethod.HEAD;
break;
case HttpMethod.Options:
other = RestSharpMethod.OPTIONS;
break;
case HttpMethod.Patch:
other = RestSharpMethod.PATCH;
break;
default:
throw new ArgumentOutOfRangeException("method", method, null);
}
return other;
}
/// <summary>
/// Provides all logic for constructing a new RestSharp <see cref="RestRequest"/>.
/// At this point, all information for querying the service is known. Here, it is simply
/// mapped into the RestSharp request.
/// </summary>
/// <param name="method">The http verb.</param>
/// <param name="path">The target path (or resource).</param>
/// <param name="options">The additional request options.</param>
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
/// GlobalConfiguration has been done before calling this method.</param>
/// <returns>[private] A new RestRequest instance.</returns>
/// <exception cref="ArgumentNullException"></exception>
private RestRequest newRequest(
HttpMethod method,
String path,
RequestOptions options,
IReadableConfiguration configuration)
{
if (path == null) throw new ArgumentNullException("path");
if (options == null) throw new ArgumentNullException("options");
if (configuration == null) throw new ArgumentNullException("configuration");
RestRequest request = new RestRequest(path, Method(method));
if (options.PathParameters != null)
{
foreach (var pathParam in options.PathParameters)
{
request.AddParameter(pathParam.Key, pathParam.Value, ParameterType.UrlSegment);
}
}
if (options.QueryParameters != null)
{
foreach (var queryParam in options.QueryParameters)
{
foreach (var value in queryParam.Value)
{
request.AddQueryParameter(queryParam.Key, value);
}
}
}
if (options.HeaderParameters != null)
{
foreach (var headerParam in options.HeaderParameters)
{
foreach (var value in headerParam.Value)
{
request.AddHeader(headerParam.Key, value);
}
}
}
if (options.FormParameters != null)
{
foreach (var formParam in options.FormParameters)
{
request.AddParameter(formParam.Key, formParam.Value);
}
}
if (options.Data != null)
{
if (options.HeaderParameters != null)
{
var contentTypes = options.HeaderParameters["Content-Type"];
if (contentTypes == null || contentTypes.Any(header => header.Contains("application/json")))
{
request.RequestFormat = DataFormat.Json;
}
else
{
// TODO: Generated client user should add additional handlers. RestSharp only supports XML and JSON, with XML as default.
}
}
else
{
// Here, we'll assume JSON APIs are more common. XML can be forced by adding produces/consumes to openapi spec explicitly.
request.RequestFormat = DataFormat.Json;
}
request.AddBody(options.Data);
}
if (options.FileParameters != null)
{
foreach (var fileParam in options.FileParameters)
{
var bytes = ClientUtils.ReadAsBytes(fileParam.Value);
var fileStream = fileParam.Value as FileStream;
if (fileStream != null)
FileParameter.Create(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name));
else
FileParameter.Create(fileParam.Key, bytes, "no_file_name_provided");
}
}
if (options.Cookies != null && options.Cookies.Count > 0)
{
foreach (var cookie in options.Cookies)
{
request.AddCookie(cookie.Name, cookie.Value);
}
}
return request;
}
private ApiResponse<T> toApiResponse<T>({{#supportsAsync}}IRestResponse<T> response{{/supportsAsync}}{{^supportsAsync}}IRestResponse response, CustomJsonCodec des{{/supportsAsync}})
{
T result = {{#supportsAsync}}response.Data{{/supportsAsync}}{{^supportsAsync}}(T)des.Deserialize(response, typeof(T)){{/supportsAsync}};
var transformed = new ApiResponse<T>(response.StatusCode, new Multimap<string, string>(), result)
{
ErrorText = response.ErrorMessage,
Cookies = new List<Cookie>()
};
if (response.Headers != null)
{
foreach (var responseHeader in response.Headers)
{
transformed.Headers.Add(responseHeader.Name, ClientUtils.ParameterToString(responseHeader.Value));
}
}
if (response.Cookies != null)
{
foreach (var responseCookies in response.Cookies)
{
transformed.Cookies.Add(
new Cookie(
responseCookies.Name,
responseCookies.Value,
responseCookies.Path,
responseCookies.Domain)
);
}
}
return transformed;
}
private {{#supportsAsync}}async Task<ApiResponse<T>>{{/supportsAsync}}{{^supportsAsync}}ApiResponse<T>{{/supportsAsync}} Exec<T>(RestRequest req, IReadableConfiguration configuration)
{
RestClient client = new RestClient(_baseUrl);
var codec = new CustomJsonCodec(configuration);
req.JsonSerializer = codec;
client.AddHandler(codec.ContentType, codec);
client.Timeout = configuration.Timeout;
if (configuration.UserAgent != null)
{
client.UserAgent = configuration.UserAgent;
}
InterceptRequest(req);
{{#supportsAsync}}
var response = await client.ExecuteTaskAsync<T>(req);
{{/supportsAsync}}
{{^supportsAsync}}
var response = client.Execute(req);
{{/supportsAsync}}
InterceptResponse(req, response);
var result = toApiResponse(response{{^supportsAsync}}, codec{{/supportsAsync}});
if (response.ErrorMessage != null)
{
result.ErrorText = response.ErrorMessage;
}
if (response.Cookies != null && response.Cookies.Count > 0)
{
if(result.Cookies == null) result.Cookies = new List<Cookie>();
foreach (var restResponseCookie in response.Cookies)
{
var cookie = new Cookie(
restResponseCookie.Name,
restResponseCookie.Value,
restResponseCookie.Path,
restResponseCookie.Domain
)
{
Comment = restResponseCookie.Comment,
CommentUri = restResponseCookie.CommentUri,
Discard = restResponseCookie.Discard,
Expired = restResponseCookie.Expired,
Expires = restResponseCookie.Expires,
HttpOnly = restResponseCookie.HttpOnly,
Port = restResponseCookie.Port,
Secure = restResponseCookie.Secure,
Version = restResponseCookie.Version
};
result.Cookies.Add(cookie);
}
}
return result;
}
{{#supportsAsync}}
#region IAsynchronousClient
public async Task<ApiResponse<T>> GetAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
var config = configuration ?? GlobalConfiguration.Instance;
return await Exec<T>(newRequest(HttpMethod.Get, path, options, config), config);
}
public async Task<ApiResponse<T>> PostAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
var config = configuration ?? GlobalConfiguration.Instance;
return await Exec<T>(newRequest(HttpMethod.Post, path, options, config), config);
}
public async Task<ApiResponse<T>> PutAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
var config = configuration ?? GlobalConfiguration.Instance;
return await Exec<T>(newRequest(HttpMethod.Put, path, options, config), config);
}
public async Task<ApiResponse<T>> DeleteAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
var config = configuration ?? GlobalConfiguration.Instance;
return await Exec<T>(newRequest(HttpMethod.Delete, path, options, config), config);
}
public async Task<ApiResponse<T>> HeadAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
var config = configuration ?? GlobalConfiguration.Instance;
return await Exec<T>(newRequest(HttpMethod.Head, path, options, config), config);
}
public async Task<ApiResponse<T>> OptionsAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
var config = configuration ?? GlobalConfiguration.Instance;
return await Exec<T>(newRequest(HttpMethod.Options, path, options, config), config);
}
public async Task<ApiResponse<T>> PatchAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
var config = configuration ?? GlobalConfiguration.Instance;
return await Exec<T>(newRequest(HttpMethod.Patch, path, options, config), config);
}
#endregion IAsynchronousClient
{{/supportsAsync}}
#region ISynchronousClient
public ApiResponse<T> Get<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
{{#supportsAsync}}
return GetAsync<T>(path, options, configuration).Result;
{{/supportsAsync}}
{{^supportsAsync}}
var config = configuration ?? GlobalConfiguration.Instance;
return Exec<T>(newRequest(HttpMethod.Get, path, options, config), config);
{{/supportsAsync}}
}
public ApiResponse<T> Post<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
{{#supportsAsync}}
return PostAsync<T>(path, options, configuration).Result;
{{/supportsAsync}}
{{^supportsAsync}}
var config = configuration ?? GlobalConfiguration.Instance;
return Exec<T>(newRequest(HttpMethod.Post, path, options, config), config);
{{/supportsAsync}}
}
public ApiResponse<T> Put<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
{{#supportsAsync}}
return PutAsync<T>(path, options, configuration).Result;
{{/supportsAsync}}
{{^supportsAsync}}
var config = configuration ?? GlobalConfiguration.Instance;
return Exec<T>(newRequest(HttpMethod.Put, path, options, config), config);
{{/supportsAsync}}
}
public ApiResponse<T> Delete<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
{{#supportsAsync}}
return DeleteAsync<T>(path, options, configuration).Result;
{{/supportsAsync}}
{{^supportsAsync}}
var config = configuration ?? GlobalConfiguration.Instance;
return Exec<T>(newRequest(HttpMethod.Delete, path, options, config), config);
{{/supportsAsync}}
}
public ApiResponse<T> Head<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
{{#supportsAsync}}
return HeadAsync<T>(path, options, configuration).Result;
{{/supportsAsync}}
{{^supportsAsync}}
var config = configuration ?? GlobalConfiguration.Instance;
return Exec<T>(newRequest(HttpMethod.Head, path, options, config), config);
{{/supportsAsync}}
}
public ApiResponse<T> Options<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
{{#supportsAsync}}
return OptionsAsync<T>(path, options, configuration).Result;
{{/supportsAsync}}
{{^supportsAsync}}
var config = configuration ?? GlobalConfiguration.Instance;
return Exec<T>(newRequest(HttpMethod.Options, path, options, config), config);
{{/supportsAsync}}
}
public ApiResponse<T> Patch<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
{
{{#supportsAsync}}
return PatchAsync<T>(path, options, configuration).Result;
{{/supportsAsync}}
{{^supportsAsync}}
var config = configuration ?? GlobalConfiguration.Instance;
return Exec<T>(newRequest(HttpMethod.Patch, path, options, config), config);
{{/supportsAsync}}
}
#endregion ISynchronousClient
}
}

View File

@ -0,0 +1,52 @@
{{>partial_header}}
using System;
namespace {{packageName}}.Client
{
/// <summary>
/// API Exception
/// </summary>
{{>visibility}} class ApiException : Exception
{
/// <summary>
/// Gets or sets the error code (HTTP status code)
/// </summary>
/// <value>The error code (HTTP status code).</value>
public int ErrorCode { get; set; }
/// <summary>
/// Gets or sets the error content (body json object)
/// </summary>
/// <value>The error content (Http response body).</value>
public {{#supportsAsync}}dynamic{{/supportsAsync}}{{^supportsAsync}}object{{/supportsAsync}} ErrorContent { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
public ApiException() {}
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="errorCode">HTTP status code.</param>
/// <param name="message">Error message.</param>
public ApiException(int errorCode, string message) : base(message)
{
this.ErrorCode = errorCode;
}
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="errorCode">HTTP status code.</param>
/// <param name="message">Error message.</param>
/// <param name="errorContent">Error content.</param>
public ApiException(int errorCode, string message, {{#supportsAsync}}dynamic{{/supportsAsync}}{{^supportsAsync}}object{{/supportsAsync}} errorContent = null) : base(message)
{
this.ErrorCode = errorCode;
this.ErrorContent = errorContent;
}
}
}

View File

@ -0,0 +1,128 @@
{{>partial_header}}
using System;
using System.Collections.Generic;
using System.Net;
namespace {{packageName}}.Client
{
/// <summary>
/// Provides a non-generic contract for the ApiResponse wrapper.
/// </summary>
public interface IApiResponse
{
/// <summary>
/// The data type of <see cref="Content"/>
/// </summary>
Type ResponseType { get; }
/// <summary>
/// The content of this response
/// </summary>
Object Content { get; }
/// <summary>
/// Gets or sets the status code (HTTP status code)
/// </summary>
/// <value>The status code.</value>
HttpStatusCode StatusCode { get; }
/// <summary>
/// Gets or sets the HTTP headers
/// </summary>
/// <value>HTTP headers</value>
Multimap<string, string> Headers { get; }
/// <summary>
/// Gets or sets any error text defined by the calling client.
/// </summary>
String ErrorText { get; set; }
/// <summary>
/// Gets or sets any cookies passed along on the response.
/// </summary>
List<Cookie> Cookies { get; set; }
}
/// <summary>
/// API Response
/// </summary>
public class ApiResponse<T> : IApiResponse
{
#region Properties
/// <summary>
/// Gets or sets the status code (HTTP status code)
/// </summary>
/// <value>The status code.</value>
public HttpStatusCode StatusCode { get; }
/// <summary>
/// Gets or sets the HTTP headers
/// </summary>
/// <value>HTTP headers</value>
public Multimap<string, string> Headers { get; }
/// <summary>
/// Gets or sets the data (parsed HTTP body)
/// </summary>
/// <value>The data.</value>
public T Data { get; }
/// <summary>
/// Gets or sets any error text defined by the calling client.
/// </summary>
public String ErrorText { get; set; }
/// <summary>
/// Gets or sets any cookies passed along on the response.
/// </summary>
public List<Cookie> Cookies { get; set; }
/// <summary>
/// The content of this response
/// </summary>
public Type ResponseType
{
get { return typeof(T); }
}
/// <summary>
/// The data type of <see cref="Content"/>
/// </summary>
public object Content
{
get { return Data; }
}
#endregion Properties
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ApiResponse{T}" /> class.
/// </summary>
/// <param name="statusCode">HTTP status code.</param>
/// <param name="headers">HTTP headers.</param>
/// <param name="data">Data (parsed HTTP body)</param>
public ApiResponse(HttpStatusCode statusCode, Multimap<string, string> headers, T data)
{
StatusCode = statusCode;
Headers = headers;
Data = data;
}
/// <summary>
/// Initializes a new instance of the <see cref="ApiResponse{T}" /> class.
/// </summary>
/// <param name="statusCode">HTTP status code.</param>
/// <param name="data">Data (parsed HTTP body)</param>
public ApiResponse(HttpStatusCode statusCode, T data)
{
StatusCode = statusCode;
Data = data;
}
#endregion Constructors
}
}

View File

@ -0,0 +1,40 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("{{packageTitle}}")]
[assembly: AssemblyDescription("{{packageDescription}}")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("{{packageCompany}}")]
[assembly: AssemblyProduct("{{packageProductName}}")]
[assembly: AssemblyCopyright("{{packageCopyright}}")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("{{packageVersion}}")]
[assembly: AssemblyFileVersion("{{packageVersion}}")]
{{^supportsAsync}}
// Settings which don't support asynchronous operations rely on non-public constructors
// This is due to how RestSharp requires the type constraint `where T : new()` in places it probably shouldn't.
[assembly: InternalsVisibleTo("RestSharp")]
[assembly: InternalsVisibleTo("NewtonSoft.Json")]
[assembly: InternalsVisibleTo("JsonSubTypes")]
{{/supportsAsync}}

View File

@ -0,0 +1,193 @@
{{>partial_header}}
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace {{packageName}}.Client
{
/// <summary>
/// Utility functions providing some benefit to API client consumers.
/// </summary>
public static class ClientUtils
{
/// <summary>
/// Sanitize filename by removing the path
/// </summary>
/// <param name="filename">Filename</param>
/// <returns>Filename</returns>
public static string SanitizeFilename(string filename)
{
Match match = Regex.Match(filename, @".*[/\\](.*)$");
return match.Success ? match.Groups[1].Value : filename;
}
/// <summary>
/// Convert params to key/value pairs.
/// Use collectionFormat to properly format lists and collections.
/// </summary>
/// <param name="collectionFormat">The swagger-supported collection format, one of: csv, tsv, ssv, pipes, multi</param>
/// <param name="name">Key name.</param>
/// <param name="value">Value object.</param>
/// <returns>A multimap of keys with 1..n associated values.</returns>
public static Multimap<string, string> ParameterToMultiMap(string collectionFormat, string name, object value)
{
var parameters = new Multimap<string, string>();
if (IsCollection(value) && collectionFormat == "multi")
{
var valueCollection = value as IEnumerable;
if (valueCollection != null)
{
foreach (var item in valueCollection)
{
parameters.Add(name, ParameterToString(item));
}
}
}
else
{
parameters.Add(name, ParameterToString(value));
}
return parameters;
}
/// <summary>
/// If parameter is DateTime, output in a formatted string (default ISO 8601), customizable with Configuration.DateTime.
/// If parameter is a list, join the list with ",".
/// Otherwise just return the string.
/// </summary>
/// <param name="obj">The parameter (header, path, query, form).</param>
/// <param name="configuration">An optional configuration instance, providing formatting options used in processing.</para>
/// <returns>Formatted string.</returns>
public static string ParameterToString(object obj, IReadableConfiguration configuration = null)
{
if (obj is DateTime)
// Return a formatted date string - Can be customized with Configuration.DateTimeFormat
// Defaults to an ISO 8601, using the known as a Round-trip date/time pattern ("o")
// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8
// For example: 2009-06-15T13:45:30.0000000
return ((DateTime)obj).ToString((configuration ?? GlobalConfiguration.Instance).DateTimeFormat);
else if (obj is DateTimeOffset)
// Return a formatted date string - Can be customized with Configuration.DateTimeFormat
// Defaults to an ISO 8601, using the known as a Round-trip date/time pattern ("o")
// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8
// For example: 2009-06-15T13:45:30.0000000
return ((DateTimeOffset)obj).ToString((configuration ?? GlobalConfiguration.Instance).DateTimeFormat);
else
{
if (obj is IList)
{
var list = obj as IList;
var flattenedString = new StringBuilder();
foreach (var param in list)
{
if (flattenedString.Length > 0)
flattenedString.Append(",");
flattenedString.Append(param);
}
return flattenedString.ToString();
}
return Convert.ToString (obj);
}
}
/// <summary>
/// Check if generic object is a collection.
/// </summary>
/// <param name="value"></param>
/// <returns>True if object is a collection type</returns>
private static bool IsCollection(object value)
{
return value is IList || value is ICollection;
}
/// <summary>
/// URL encode a string
/// Credit/Ref: https://github.com/restsharp/RestSharp/blob/master/RestSharp/Extensions/StringExtensions.cs#L50
/// </summary>
/// <param name="input">String to be URL encoded</param>
/// <returns>Byte array</returns>
public static string UrlEncode(string input)
{
const int maxLength = 32766;
if (input == null)
{
throw new ArgumentNullException("input");
}
if (input.Length <= maxLength)
{
return Uri.EscapeDataString(input);
}
StringBuilder sb = new StringBuilder(input.Length * 2);
int index = 0;
while (index < input.Length)
{
int length = Math.Min(input.Length - index, maxLength);
string subString = input.Substring(index, length);
sb.Append(Uri.EscapeDataString(subString));
index += subString.Length;
}
return sb.ToString();
}
/// <summary>
/// Encode string in base64 format.
/// </summary>
/// <param name="text">String to be encoded.</param>
/// <returns>Encoded string.</returns>
public static string Base64Encode(string text)
{
return System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(text));
}
/// <summary>
/// Convert stream to byte array
/// </summary>
/// <param name="inputStream">Input stream to be converted</param>
/// <returns>Byte array</returns>
public static byte[] ReadAsBytes(Stream inputStream)
{
byte[] buf = new byte[16*1024];
using (MemoryStream ms = new MemoryStream())
{
int count;
while ((count = inputStream.Read(buf, 0, buf.Length)) > 0)
{
ms.Write(buf, 0, count);
}
return ms.ToArray();
}
}
/// <summary>
/// Dynamically cast the object into target type.
/// </summary>
/// <param name="fromObject">Object to be casted</param>
/// <param name="toObject">Target type</param>
/// <returns>Casted object</returns>
{{#supportsAsync}}
public static dynamic ConvertType(dynamic fromObject, Type toObject)
{{/supportsAsync}}
{{^supportsAsync}}
public static object ConvertType<T>(T fromObject, Type toObject) where T : class
{{/supportsAsync}}
{
return Convert.ChangeType(fromObject, toObject);
}
}
}

View File

@ -0,0 +1,395 @@
{{>partial_header}}
using System;
using System.Reflection;
{{^net35}}
using System.Collections.Concurrent;
{{/net35}}
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace {{packageName}}.Client
{
/// <summary>
/// Represents a set of configuration settings
/// </summary>
{{>visibility}} class Configuration : IReadableConfiguration
{
#region Constants
/// <summary>
/// Version of the package.
/// </summary>
/// <value>Version of the package.</value>
public const string Version = "{{packageVersion}}";
/// <summary>
/// Identifier for ISO 8601 DateTime Format
/// </summary>
/// <remarks>See https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8 for more information.</remarks>
// ReSharper disable once InconsistentNaming
public const string ISO8601_DATETIME_FORMAT = "o";
#endregion Constants
#region Static Members
/// <summary>
/// Default creation of exceptions for a given method name and response object
/// </summary>
public static readonly ExceptionFactory DefaultExceptionFactory = (methodName, response) =>
{
var status = (int)response.StatusCode;
if (status >= 400)
{
return new ApiException(status,
string.Format("Error calling {0}: {1}", methodName, response.Content),
response.Content);
}
{{^netStandard}}if (status == 0)
{
return new ApiException(status,
string.Format("Error calling {0}: {1}", methodName, response.ErrorText), response.ErrorText);
}{{/netStandard}}
return null;
};
#endregion Static Members
#region Private Members
/// <summary>
/// Defines the base path of the target API server.
/// Example: http://localhost:3000/v1/
/// </summary>
private String _basePath;
/// <summary>
/// Gets or sets the API key based on the authentication name.
/// This is the key and value comprising the "secret" for acessing an API.
/// </summary>
/// <value>The API key.</value>
private IDictionary<string, string> _apiKey;
/// <summary>
/// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name.
/// </summary>
/// <value>The prefix of the API key.</value>
private IDictionary<string, string> _apiKeyPrefix;
private string _dateTimeFormat = ISO8601_DATETIME_FORMAT;
private string _tempFolderPath = Path.GetTempPath();
#endregion Private Members
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="Configuration" /> class
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("ReSharper", "VirtualMemberCallInConstructor")]
public Configuration()
{
UserAgent = "{{#httpUserAgent}}{{.}}{{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{packageVersion}}/csharp{{/httpUserAgent}}";
BasePath = "{{{basePath}}}";
DefaultHeader = new {{^net35}}Concurrent{{/net35}}Dictionary<string, string>();
ApiKey = new {{^net35}}Concurrent{{/net35}}Dictionary<string, string>();
ApiKeyPrefix = new {{^net35}}Concurrent{{/net35}}Dictionary<string, string>();
// Setting Timeout has side effects (forces ApiClient creation).
Timeout = 100000;
}
/// <summary>
/// Initializes a new instance of the <see cref="Configuration" /> class
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("ReSharper", "VirtualMemberCallInConstructor")]
public Configuration(
IDictionary<string, string> defaultHeader,
IDictionary<string, string> apiKey,
IDictionary<string, string> apiKeyPrefix,
string basePath = "{{{basePath}}}") : this()
{
if (string.{{^net35}}IsNullOrWhiteSpace{{/net35}}{{#net35}}IsNullOrEmpty{{/net35}}(basePath))
throw new ArgumentException("The provided basePath is invalid.", "basePath");
if (defaultHeader == null)
throw new ArgumentNullException("defaultHeader");
if (apiKey == null)
throw new ArgumentNullException("apiKey");
if (apiKeyPrefix == null)
throw new ArgumentNullException("apiKeyPrefix");
BasePath = basePath;
foreach (var keyValuePair in defaultHeader)
{
DefaultHeader.Add(keyValuePair);
}
foreach (var keyValuePair in apiKey)
{
ApiKey.Add(keyValuePair);
}
foreach (var keyValuePair in apiKeyPrefix)
{
ApiKeyPrefix.Add(keyValuePair);
}
}
#endregion Constructors
#region Properties
/// <summary>
/// Gets or sets the base path for API access.
/// </summary>
public virtual string BasePath {
get { return _basePath; }
set {
_basePath = value;
}
}
/// <summary>
/// Gets or sets the default header.
/// </summary>
public virtual IDictionary<string, string> DefaultHeader { get; set; }
/// <summary>
/// Gets or sets the HTTP timeout (milliseconds) of ApiClient. Default to 100000 milliseconds.
/// </summary>
public virtual int Timeout { get; set; }
/// <summary>
/// Gets or sets the HTTP user agent.
/// </summary>
/// <value>Http user agent.</value>
public virtual string UserAgent { get; set; }
/// <summary>
/// Gets or sets the username (HTTP basic authentication).
/// </summary>
/// <value>The username.</value>
public virtual string Username { get; set; }
/// <summary>
/// Gets or sets the password (HTTP basic authentication).
/// </summary>
/// <value>The password.</value>
public virtual string Password { get; set; }
/// <summary>
/// Gets the API key with prefix.
/// </summary>
/// <param name="apiKeyIdentifier">API key identifier (authentication scheme).</param>
/// <returns>API key with prefix.</returns>
public string GetApiKeyWithPrefix(string apiKeyIdentifier)
{
string apiKeyValue;
ApiKey.TryGetValue (apiKeyIdentifier, out apiKeyValue);
string apiKeyPrefix;
if (ApiKeyPrefix.TryGetValue(apiKeyIdentifier, out apiKeyPrefix))
{
return apiKeyPrefix + " " + apiKeyValue;
}
return apiKeyValue;
}
/// <summary>
/// Gets or sets the access token for OAuth2 authentication.
///
/// This helper property simplifies code generation.
/// </summary>
/// <value>The access token.</value>
public virtual string AccessToken { get; set; }
/// <summary>
/// Gets or sets the temporary folder path to store the files downloaded from the server.
/// </summary>
/// <value>Folder path.</value>
public virtual string TempFolderPath
{
get { return _tempFolderPath; }
set
{
if (string.IsNullOrEmpty(value))
{
_tempFolderPath = Path.GetTempPath();
return;
}
// create the directory if it does not exist
if (!Directory.Exists(value))
{
Directory.CreateDirectory(value);
}
// check if the path contains directory separator at the end
if (value[value.Length - 1] == Path.DirectorySeparatorChar)
{
_tempFolderPath = value;
}
else
{
_tempFolderPath = value + Path.DirectorySeparatorChar;
}
}
}
/// <summary>
/// Gets or sets the the date time format used when serializing in the ApiClient
/// By default, it's set to ISO 8601 - "o", for others see:
/// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
/// and https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx
/// No validation is done to ensure that the string you're providing is valid
/// </summary>
/// <value>The DateTimeFormat string</value>
public virtual string DateTimeFormat
{
get { return _dateTimeFormat; }
set
{
if (string.IsNullOrEmpty(value))
{
// Never allow a blank or null string, go back to the default
_dateTimeFormat = ISO8601_DATETIME_FORMAT;
return;
}
// Caution, no validation when you choose date time format other than ISO 8601
// Take a look at the above links
_dateTimeFormat = value;
}
}
/// <summary>
/// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name.
///
/// Whatever you set here will be prepended to the value defined in AddApiKey.
///
/// An example invocation here might be:
/// <example>
/// ApiKeyPrefix["Authorization"] = "Bearer";
/// </example>
/// … where ApiKey["Authorization"] would then be used to set the value of your bearer token.
///
/// <remarks>
/// OAuth2 workflows should set tokens via AccessToken.
/// </remarks>
/// </summary>
/// <value>The prefix of the API key.</value>
public virtual IDictionary<string, string> ApiKeyPrefix
{
get { return _apiKeyPrefix; }
set
{
if (value == null)
{
throw new InvalidOperationException("ApiKeyPrefix collection may not be null.");
}
_apiKeyPrefix = value;
}
}
/// <summary>
/// Gets or sets the API key based on the authentication name.
/// </summary>
/// <value>The API key.</value>
public virtual IDictionary<string, string> ApiKey
{
get { return _apiKey; }
set
{
if (value == null)
{
throw new InvalidOperationException("ApiKey collection may not be null.");
}
_apiKey = value;
}
}
#endregion Properties
#region Methods
/// <summary>
/// Returns a string with essential information for debugging.
/// </summary>
public static String ToDebugReport()
{
String report = "C# SDK ({{{packageName}}}) Debug Report:\n";
{{^netStandard}}
{{^supportsUWP}}
report += " OS: " + System.Environment.OSVersion + "\n";
report += " .NET Framework Version: " + System.Environment.Version + "\n";
{{/supportsUWP}}
{{/netStandard}}
{{#netStandard}}
report += " OS: " + System.Runtime.InteropServices.RuntimeInformation.OSDescription + "\n";
{{/netStandard}}
report += " Version of the API: {{{version}}}\n";
report += " SDK Package Version: {{{packageVersion}}}\n";
return report;
}
/// <summary>
/// Add Api Key Header.
/// </summary>
/// <param name="key">Api Key name.</param>
/// <param name="value">Api Key value.</param>
/// <returns></returns>
public void AddApiKey(string key, string value)
{
ApiKey[key] = value;
}
/// <summary>
/// Sets the API key prefix.
/// </summary>
/// <param name="key">Api Key name.</param>
/// <param name="value">Api Key value.</param>
public void AddApiKeyPrefix(string key, string value)
{
ApiKeyPrefix[key] = value;
}
#endregion Methods
#region Static Members
public static IReadableConfiguration MergeConfigurations(IReadableConfiguration first, IReadableConfiguration second)
{
if (second == null) return first ?? GlobalConfiguration.Instance;
Dictionary<string, string> apiKey = first.ApiKey.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
Dictionary<string, string> apiKeyPrefix = first.ApiKeyPrefix.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
Dictionary<string, string> defaultHeader = first.DefaultHeader.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
foreach (var kvp in second.ApiKey) apiKey[kvp.Key] = kvp.Value;
foreach (var kvp in second.ApiKeyPrefix) apiKeyPrefix[kvp.Key] = kvp.Value;
foreach (var kvp in second.DefaultHeader) defaultHeader[kvp.Key] = kvp.Value;
var config = new Configuration
{
ApiKey = apiKey,
ApiKeyPrefix = apiKeyPrefix,
DefaultHeader = defaultHeader,
BasePath = second.BasePath ?? first.BasePath,
Timeout = second.Timeout,
UserAgent = second.UserAgent ?? first.UserAgent,
Username = second.Username ?? first.Username,
Password = second.Password ?? first.Password,
AccessToken = second.AccessToken ?? first.AccessToken,
TempFolderPath = second.TempFolderPath ?? first.TempFolderPath,
DateTimeFormat = second.DateTimeFormat ?? first.DateTimeFormat
};
return config;
}
#endregion Static Members
}
}

View File

@ -0,0 +1,14 @@
{{>partial_header}}
using System;
namespace {{packageName}}.Client
{
/// <summary>
/// A delegate to ExceptionFactory method
/// </summary>
/// <param name="methodName">Method name</param>
/// <param name="response">Response</param>
/// <returns>Exceptions</returns>
{{>visibility}} delegate Exception ExceptionFactory(string methodName, IApiResponse response);
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Ref: https://github.com/Fody/Fody -->
<Weavers>
<PropertyChanged/>
</Weavers>

View File

@ -0,0 +1,59 @@
{{>partial_header}}
using System.Collections.Generic;
namespace {{packageName}}.Client
{
/// <summary>
/// <see cref="GlobalConfiguration"/> provides a compile-time extension point for globally configuring
/// API Clients.
/// </summary>
/// <remarks>
/// A customized implementation via partial class may reside in another file and may
/// be excluded from automatic generation via a .openapi-generator-ignore file.
/// </remarks>
public partial class GlobalConfiguration : Configuration
{
#region Private Members
private static readonly object GlobalConfigSync = new { };
private static IReadableConfiguration _globalConfiguration;
#endregion Private Members
#region Constructors
/// <inheritdoc />
private GlobalConfiguration()
{
}
/// <inheritdoc />
public GlobalConfiguration(IDictionary<string, string> defaultHeader, IDictionary<string, string> apiKey, IDictionary<string, string> apiKeyPrefix, string basePath = "http://localhost:3000/api") : base(defaultHeader, apiKey, apiKeyPrefix, basePath)
{
}
static GlobalConfiguration()
{
Instance = new GlobalConfiguration();
}
#endregion Constructors
/// <summary>
/// Gets or sets the default Configuration.
/// </summary>
/// <value>Configuration.</value>
public static IReadableConfiguration Instance
{
get { return _globalConfiguration; }
set
{
lock (GlobalConfigSync)
{
_globalConfiguration = value;
}
}
}
}
}

View File

@ -0,0 +1,18 @@
{{>partial_header}}
namespace {{packageName}}.Client
{
/// <summary>
/// Http methods supported by swagger
/// </summary>
public enum HttpMethod
{
Get,
Post,
Put,
Delete,
Head,
Options,
Patch
}
}

View File

@ -0,0 +1,29 @@
{{>partial_header}}
using System;
namespace {{packageName}}.Client
{
/// <summary>
/// Represents configuration aspects required to interact with the API endpoints.
/// </summary>
{{>visibility}} interface IApiAccessor
{
/// <summary>
/// Gets or sets the configuration object
/// </summary>
/// <value>An instance of the Configuration</value>
IReadableConfiguration Configuration {get; set;}
/// <summary>
/// Gets the base path of the API client.
/// </summary>
/// <value>The base path</value>
String GetBasePath();
/// <summary>
/// Provides a factory method hook for the creation of exceptions.
/// </summary>
ExceptionFactory ExceptionFactory { get; set; }
}
}

View File

@ -0,0 +1,87 @@
{{>partial_header}}
{{^supportsAsync}}/*{{/supportsAsync}}
using System;
using System.Threading.Tasks;
namespace {{packageName}}.Client
{
/// <summary>
/// Contract for Asynchronous RESTful API interactions.
///
/// This interface allows consumers to provide a custom API accessor client.
/// </summary>
public interface IAsynchronousClient
{
/// <summary>
/// Executes a non-blocking call to some <paramref name="path"/> using the GET http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
Task<ApiResponse<T>> GetAsync<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
/// <summary>
/// Executes a non-blocking call to some <paramref name="path"/> using the POST http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
Task<ApiResponse<T>> PostAsync<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
/// <summary>
/// Executes a non-blocking call to some <paramref name="path"/> using the PUT http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
Task<ApiResponse<T>> PutAsync<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
/// <summary>
/// Executes a non-blocking call to some <paramref name="path"/> using the DELETE http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
Task<ApiResponse<T>> DeleteAsync<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
/// <summary>
/// Executes a non-blocking call to some <paramref name="path"/> using the HEAD http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
Task<ApiResponse<T>> HeadAsync<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
/// <summary>
/// Executes a non-blocking call to some <paramref name="path"/> using the OPTIONS http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
Task<ApiResponse<T>> OptionsAsync<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
/// <summary>
/// Executes a non-blocking call to some <paramref name="path"/> using the PATCH http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
Task<ApiResponse<T>> PatchAsync<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
}
}
{{^supportsAsync}}*/{{/supportsAsync}}

View File

@ -0,0 +1,85 @@
{{>partial_header}}
using System.Collections.Generic;
namespace {{packageName}}.Client
{
/// <summary>
/// Represents a readable-only configuration contract.
/// </summary>
public interface IReadableConfiguration
{
/// <summary>
/// Gets the access token.
/// </summary>
/// <value>Access token.</value>
string AccessToken { get; }
/// <summary>
/// Gets the API key.
/// </summary>
/// <value>API key.</value>
IDictionary<string, string> ApiKey { get; }
/// <summary>
/// Gets the API key prefix.
/// </summary>
/// <value>API key prefix.</value>
IDictionary<string, string> ApiKeyPrefix { get; }
/// <summary>
/// Gets the base path.
/// </summary>
/// <value>Base path.</value>
string BasePath { get; }
/// <summary>
/// Gets the date time format.
/// </summary>
/// <value>Date time foramt.</value>
string DateTimeFormat { get; }
/// <summary>
/// Gets the default header.
/// </summary>
/// <value>Default header.</value>
IDictionary<string, string> DefaultHeader { get; }
/// <summary>
/// Gets the temp folder path.
/// </summary>
/// <value>Temp folder path.</value>
string TempFolderPath { get; }
/// <summary>
/// Gets the HTTP connection timeout (in milliseconds)
/// </summary>
/// <value>HTTP connection timeout.</value>
int Timeout { get; }
/// <summary>
/// Gets the user agent.
/// </summary>
/// <value>User agent.</value>
string UserAgent { get; }
/// <summary>
/// Gets the username.
/// </summary>
/// <value>Username.</value>
string Username { get; }
/// <summary>
/// Gets the password.
/// </summary>
/// <value>Password.</value>
string Password { get; }
/// <summary>
/// Gets the API key with prefix.
/// </summary>
/// <param name="apiKeyIdentifier">API key identifier (authentication scheme).</param>
/// <returns>API key with prefix.</returns>
string GetApiKeyWithPrefix(string apiKeyIdentifier);
}
}

View File

@ -0,0 +1,85 @@
{{>partial_header}}
using System;
using System.IO;
namespace {{packageName}}.Client
{
/// <summary>
/// Contract for Synchronous RESTful API interactions.
///
/// This interface allows consumers to provide a custom API accessor client.
/// </summary>
public interface ISynchronousClient
{
/// <summary>
/// Executes a blocking call to some <paramref name="path"/> using the GET http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
ApiResponse<T> Get<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
/// <summary>
/// Executes a blocking call to some <paramref name="path"/> using the POST http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
ApiResponse<T> Post<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
/// <summary>
/// Executes a blocking call to some <paramref name="path"/> using the PUT http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
ApiResponse<T> Put<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
/// <summary>
/// Executes a blocking call to some <paramref name="path"/> using the DELETE http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
ApiResponse<T> Delete<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
/// <summary>
/// Executes a blocking call to some <paramref name="path"/> using the HEAD http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
ApiResponse<T> Head<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
/// <summary>
/// Executes a blocking call to some <paramref name="path"/> using the OPTIONS http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
ApiResponse<T> Options<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
/// <summary>
/// Executes a blocking call to some <paramref name="path"/> using the PATCH http verb.
/// </summary>
/// <param name="path">The relative path to invoke.</param>
/// <param name="options">The request parameters to pass along to the client.</param>
/// <param name="configuration">Per-request configurable settings.</param>
/// <typeparam name="T">The return type.</typeparam>
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
ApiResponse<T> Patch<T>(String path, RequestOptions options, IReadableConfiguration configuration = null);
}
}

View File

@ -0,0 +1,125 @@
{{>partial_header}}
using System.Collections.Generic;
using System.Linq;
using JsonSubTypes;
using Newtonsoft.Json;
using NUnit.Framework;
using {{packageName}}.{{apiPackage}};
using {{packageName}}.{{modelPackage}};
using {{packageName}}.Client;
namespace {{packageName}}.Test.Client
{
public class JsonSubTypesTests
{
[Test]
public void TestSimpleJsonSubTypesExample()
{
var annimal =
JsonConvert.DeserializeObject<IAnimal>("{\"Kind\":\"Dog\",\"Breed\":\"Jack Russell Terrier\"}");
Assert.AreEqual("Jack Russell Terrier", (annimal as Dog)?.Breed);
}
[Test]
public void DeserializeObjectWithCustomMapping()
{
var annimal =
JsonConvert.DeserializeObject<Animal2>("{\"Sound\":\"Bark\",\"Breed\":\"Jack Russell Terrier\"}");
Assert.AreEqual("Jack Russell Terrier", (annimal as Dog2)?.Breed);
}
[Test]
public void DeserializeObjectMappingByPropertyPresence()
{
string json =
"[{\"Department\":\"Department1\",\"JobTitle\":\"JobTitle1\",\"FirstName\":\"FirstName1\",\"LastName\":\"LastName1\"}," +
"{\"Department\":\"Department1\",\"JobTitle\":\"JobTitle1\",\"FirstName\":\"FirstName1\",\"LastName\":\"LastName1\"}," +
"{\"Skill\":\"Painter\",\"FirstName\":\"FirstName1\",\"LastName\":\"LastName1\"}]";
var persons = JsonConvert.DeserializeObject<ICollection<Person>>(json);
Assert.AreEqual("Painter", (persons.Last() as Artist)?.Skill);
}
}
[JsonConverter(typeof(JsonSubtypes), "Kind")]
public interface IAnimal
{
string Kind { get; }
}
public class Dog : IAnimal
{
public Dog()
{
Kind = "Dog";
}
public string Kind { get; }
public string Breed { get; set; }
}
class Cat : IAnimal
{
public Cat()
{
Kind = "Cat";
}
public string Kind { get; }
bool Declawed { get; set; }
}
[JsonConverter(typeof(JsonSubtypes), "Sound")]
[JsonSubtypes.KnownSubType(typeof(Dog2), "Bark")]
[JsonSubtypes.KnownSubType(typeof(Cat2), "Meow")]
public class Animal2
{
public virtual string Sound { get; }
public string Color { get; set; }
}
public class Dog2 : Animal2
{
public Dog2()
{
Sound = "Bark";
}
public override string Sound { get; }
public string Breed { get; set; }
}
public class Cat2 : Animal2
{
public Cat2()
{
Sound = "Meow";
}
public override string Sound { get; }
public bool Declawed { get; set; }
}
[JsonConverter(typeof(JsonSubtypes))]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(Employee), "JobTitle")]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(Artist), "Skill")]
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Employee : Person
{
public string Department { get; set; }
public string JobTitle { get; set; }
}
public class Artist : Person
{
public string Skill { get; set; }
}
}

View File

@ -0,0 +1,214 @@
{{>partial_header}}
using System;
using System.Collections;
{{^net35}}using System.Collections.Concurrent;{{/net35}}
using System.Collections.Generic;
namespace {{packageName}}.Client
{
/// <summary>
/// A dictionary in which one key has many associated values.
/// </summary>
/// <typeparam name="T">The type of the key</typeparam>
/// <typeparam name="TValue">The type of the value associated with the key.</typeparam>
public class Multimap<T, TValue> : IDictionary<T, IList<TValue>>
{
#region Private Fields
private readonly {{^net35}}Concurrent{{/net35}}Dictionary<T, IList<TValue>> _dictionary =
new {{^net35}}Concurrent{{/net35}}Dictionary<T, IList<TValue>>();
#endregion Private Fields
#region Enumerators
public IEnumerator<KeyValuePair<T, IList<TValue>>> GetEnumerator()
{
return _dictionary.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _dictionary.GetEnumerator();
}
#endregion Enumerators
#region Public Members
public void Add(KeyValuePair<T, IList<TValue>> item)
{
if (!TryAdd(item.Key, item.Value))
throw new InvalidOperationException("Could not add values to Multimap.");
}
public void Clear()
{
_dictionary.Clear();
}
public bool Contains(KeyValuePair<T, IList<TValue>> item)
{
throw new NotImplementedException();
}
public void CopyTo(KeyValuePair<T, IList<TValue>>[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public bool Remove(KeyValuePair<T, IList<TValue>> item)
{
throw new NotImplementedException();
}
public int Count
{
get
{
return _dictionary.Count;
}
}
public bool IsReadOnly
{
get
{
return false;
}
}
public void Add(T key, IList<TValue> value)
{
if (value != null && value.Count > 0)
{
IList<TValue> list;
if (_dictionary.TryGetValue(key, out list))
{
foreach (var k in value) list.Add(k);
}
else
{
list = new List<TValue>(value);
if (!TryAdd(key, list))
throw new InvalidOperationException("Could not add values to Multimap.");
}
}
}
public bool ContainsKey(T key)
{
return _dictionary.ContainsKey(key);
}
public bool Remove(T key)
{
IList<TValue> list;
return TryRemove(key, out list);
}
public bool TryGetValue(T key, out IList<TValue> value)
{
return _dictionary.TryGetValue(key, out value);
}
public IList<TValue> this[T key]
{
get
{
return _dictionary[key];
}
set { _dictionary[key] = value; }
}
public ICollection<T> Keys
{
get
{
return _dictionary.Keys;
}
}
public ICollection<IList<TValue>> Values
{
get
{
return _dictionary.Values;
}
}
public void CopyTo(Array array, int index)
{
((ICollection) _dictionary).CopyTo(array, index);
}
public void Add(T key, TValue value)
{
if (value != null)
{
IList<TValue> list;
if (_dictionary.TryGetValue(key, out list))
{
list.Add(value);
}
else
{
list = new List<TValue>();
list.Add(value);
if (!TryAdd(key, list))
throw new InvalidOperationException("Could not add value to Multimap.");
}
}
}
#endregion Public Members
#region Private Members
/**
* Helper method to encapsulate generator differences between dictioary types.
*/
private bool TryRemove(T key, out IList<TValue> value)
{
{{^net35}}return _dictionary.TryRemove(key, out value);{{/net35}}
{{#net35}}try
{
_dictionary.TryGetValue(key, out value);
_dictionary.Remove(key);
}
#pragma warning disable 168
catch (ArgumentException e)
#pragma warning restore 168
{
value = null;
return false;
}
return true;{{/net35}}
}
/**
* Helper method to encapsulate generator differences between dictioary types.
*/
private bool TryAdd(T key, IList<TValue> value)
{
{{^net35}}return _dictionary.TryAdd(key, value);{{/net35}}
{{#net35}}
try
{
_dictionary.Add(key, value);
}
#pragma warning disable 168
catch (ArgumentException e)
#pragma warning restore 168
{
return false;
}
return true;
{{/net35}}
}
#endregion Private Members
}
}

View File

@ -0,0 +1,21 @@
{{>partial_header}}
using Newtonsoft.Json.Converters;
namespace {{packageName}}.Client
{
/// <summary>
/// Formatter for 'date' openapi formats ss defined by full-date - RFC3339
/// see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#data-types
/// </summary>
public class OpenAPIDateConverter : IsoDateTimeConverter
{
/// <summary>
/// Initializes a new instance of the <see cref="OpenAPIDateConverter" /> class.
/// </summary>
public OpenAPIDateConverter()
{
// full-date = date-fullyear "-" date-month "-" date-mday
DateTimeFormat = "yyyy-MM-dd";
}
}
}

View File

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
{{#appName}}
{{{appName}}}
{{/appName}}
{{#appDescription}}
{{{appDescription}}}
{{/appDescription}}
{{#version}}OpenAPI spec version: {{version}}{{/version}}
{{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
-->
<Project ToolsVersion="{{^netStandard}}12.0{{/netStandard}}{{#netStandard}}14.0{{/netStandard}}" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
{{#netStandard}}<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>{{/netStandard}}
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{{packageGuid}}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>{{packageName}}</RootNamespace>
<AssemblyName>{{packageName}}</AssemblyName>
{{#netStandard}}
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkVersion>{{targetFramework}}</TargetFrameworkVersion>
{{/netStandard}}
{{^netStandard}}
{{^supportsUWP}}
<TargetFrameworkVersion>{{targetFramework}}</TargetFrameworkVersion>
{{/supportsUWP}}
{{#supportsUWP}}
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
{{/supportsUWP}}
{{/netStandard}}
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
{{^netStandard}}
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
<Reference Include="Newtonsoft.Json">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\Newtonsoft.Json.10.0.3\lib\{{targetFrameworkNuget}}\Newtonsoft.Json.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\Newtonsoft.Json.10.0.3\lib\{{targetFrameworkNuget}}\Newtonsoft.Json.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\Newtonsoft.Json.10.0.3\lib\{{targetFrameworkNuget}}\Newtonsoft.Json.dll</HintPath>
<HintPath Condition="Exists('{{binRelativePath}}')">{{binRelativePath}}\Newtonsoft.Json.10.0.3\lib\{{targetFrameworkNuget}}\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="JsonSubTypes">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\JsonSubTypes.1.2.0\lib\{{targetFrameworkNuget}}\JsonSubTypes.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\JsonSubTypes.1.2.0\lib\{{targetFrameworkNuget}}\JsonSubTypes.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\JsonSubTypes.1.2.0\lib\{{targetFrameworkNuget}}\JsonSubTypes.dll</HintPath>
<HintPath Condition="Exists('{{binRelativePath}}')">{{binRelativePath}}\JsonSubTypes.1.2.0\lib\{{targetFrameworkNuget}}\JsonSubTypes.dll</HintPath>
</Reference>
<Reference Include="RestSharp">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\RestSharp.105.1.0\lib\{{#isNet40}}net4{{/isNet40}}{{^isNet40}}{{targetFrameworkNuget}}{{/isNet40}}\RestSharp.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\RestSharp.105.1.0\lib\{{#isNet40}}net4{{/isNet40}}{{^isNet40}}{{targetFrameworkNuget}}{{/isNet40}}\RestSharp.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\RestSharp.105.1.0\lib\{{#isNet40}}net4{{/isNet40}}{{^isNet40}}{{targetFrameworkNuget}}{{/isNet40}}\RestSharp.dll</HintPath>
<HintPath Condition="Exists('{{binRelativePath}}')">{{binRelativePath}}\RestSharp.105.1.0\lib\{{#isNet40}}net4{{/isNet40}}{{^isNet40}}{{targetFrameworkNuget}}{{/isNet40}}\RestSharp.dll</HintPath>
</Reference>
{{#generatePropertyChanged}}
<Reference Include="PropertyChanged">
<HintPath>..\..\packages\PropertyChanged.Fody.1.51.3\Lib\portable-net4+sl4+wp8+win8+wpa81+MonoAndroid16+MonoTouch40\PropertyChanged.dll</HintPath>
</Reference>
{{/generatePropertyChanged}}
{{/netStandard}}
{{#netStandard}}
<!-- A reference to the entire .NET Framework is automatically included -->
<None Include="project.json" />
{{/netStandard}}
</ItemGroup>
<ItemGroup>
<Compile Include="**\*.cs"
Exclude="obj\**" />
</ItemGroup>
{{^netStandard}}
<ItemGroup>
<None Include="packages.config" />
{{#generatePropertyChanged}}
<None Include="FodyWeavers.xml" />
{{/generatePropertyChanged}}
</ItemGroup>
<Import Project="$(MsBuildToolsPath)\Microsoft.CSharp.targets" />
{{#generatePropertyChanged}}
<Import Project="..\..\packages\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets" Condition="Exists('..\..\packages\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets')" />
{{/generatePropertyChanged}}
{{/netStandard}}
{{#netStandard}}
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
{{/netStandard}}
</Project>

View File

@ -0,0 +1,206 @@
# {{packageName}} - the C# library for the {{appName}}
{{#appDescription}}
{{{appDescription}}}
{{/appDescription}}
This C# SDK is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
- API version: {{appVersion}}
- SDK version: {{packageVersion}}
{{^hideGenerationTimestamp}}
- Build date: {{generatedDate}}
{{/hideGenerationTimestamp}}
- Build package: {{generatorClass}}
{{#infoUrl}}
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
{{/infoUrl}}
<a name="frameworks-supported"></a>
## Frameworks supported
{{#netStandard}}
- .NET Core >=1.0
- .NET Framework >=4.6
- Mono/Xamarin >=vNext
- UWP >=10.0
{{/netStandard}}
{{^netStandard}}
{{^supportsUWP}}
- .NET 4.0 or later
- Windows Phone 7.1 (Mango)
{{/supportsUWP}}
{{#supportsUWP}}
- UWP
{{/supportsUWP}}
{{/netStandard}}
<a name="dependencies"></a>
## Dependencies
{{#netStandard}}
- FubarCoder.RestSharp.Portable.Core >=4.0.7
- FubarCoder.RestSharp.Portable.HttpClient >=4.0.7
- Newtonsoft.Json >=10.0.3
{{/netStandard}}
{{^netStandard}}
- [RestSharp](https://www.nuget.org/packages/RestSharp) - 105.1.0 or later
- [Json.NET](https://www.nuget.org/packages/Newtonsoft.Json/) - 7.0.0 or later
- [JsonSubTypes](https://www.nuget.org/packages/JsonSubTypes/) - 1.2.0 or later
The DLLs included in the package may not be the latest version. We recommend using [NuGet](https://docs.nuget.org/consume/installing-nuget) to obtain the latest version of the packages:
```
Install-Package RestSharp
Install-Package Newtonsoft.Json
Install-Package JsonSubTypes
```
NOTE: RestSharp versions greater than 105.1.0 have a bug which causes file uploads to fail. See [RestSharp#742](https://github.com/restsharp/RestSharp/issues/742)
{{/netStandard}}
<a name="installation"></a>
## Installation
{{#netStandard}}
Generate the DLL using your preferred tool
{{/netStandard}}
{{^netStandard}}
Run the following command to generate the DLL
- [Mac/Linux] `/bin/sh build.sh`
- [Windows] `build.bat`
{{/netStandard}}
Then include the DLL (under the `bin` folder) in the C# project, and use the namespaces:
```csharp
using {{packageName}}.{{apiPackage}};
using {{packageName}}.Client;
using {{packageName}}.{{modelPackage}};
```
{{^netStandard}}
<a name="packaging"></a>
## Packaging
A `.nuspec` is included with the project. You can follow the Nuget quickstart to [create](https://docs.microsoft.com/en-us/nuget/quickstart/create-and-publish-a-package#create-the-package) and [publish](https://docs.microsoft.com/en-us/nuget/quickstart/create-and-publish-a-package#publish-the-package) packages.
This `.nuspec` uses placeholders from the `.csproj`, so build the `.csproj` directly:
```
nuget pack -Build -OutputDirectory out {{packageName}}.csproj
```
Then, publish to a [local feed](https://docs.microsoft.com/en-us/nuget/hosting-packages/local-feeds) or [other host](https://docs.microsoft.com/en-us/nuget/hosting-packages/overview) and consume the new package via Nuget as usual.
{{/netStandard}}
<a name="getting-started"></a>
## Getting Started
```csharp
using System;
using System.Diagnostics;
using {{packageName}}.{{apiPackage}};
using {{packageName}}.Client;
using {{packageName}}.{{modelPackage}};
namespace Example
{
public class {{operationId}}Example
{
public void main()
{
{{#apiInfo}}{{#apis}}{{#-first}}{{#operations}}{{#operation}}{{#-first}}
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasic}}
// Configure HTTP basic authorization: {{{name}}}
Configuration.Default.Username = "YOUR_USERNAME";
Configuration.Default.Password = "YOUR_PASSWORD";
{{/isBasic}}
{{#isApiKey}}
// Configure API key authorization: {{{name}}}
Configuration.Default.ApiKey.Add("{{{keyParamName}}}", "YOUR_API_KEY");
// Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
// Configuration.Default.ApiKeyPrefix.Add("{{{keyParamName}}}", "Bearer");
{{/isApiKey}}
{{#isOAuth}}
// Configure OAuth2 access token for authorization: {{{name}}}
Configuration.Default.AccessToken = "YOUR_ACCESS_TOKEN";
{{/isOAuth}}
{{/authMethods}}
{{/hasAuthMethods}}
var apiInstance = new {{classname}}();
{{#allParams}}
{{#isPrimitiveType}}
var {{paramName}} = {{{example}}}; // {{{dataType}}} | {{{description}}}{{^required}} (optional) {{/required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}
{{/isPrimitiveType}}
{{^isPrimitiveType}}
var {{paramName}} = new {{{dataType}}}(); // {{{dataType}}} | {{{description}}}{{^required}} (optional) {{/required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}
{{/isPrimitiveType}}
{{/allParams}}
try
{
{{#summary}}
// {{{.}}}
{{/summary}}
{{#returnType}}{{{.}}} result = {{/returnType}}apiInstance.{{{operationId}}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{#returnType}}
Debug.WriteLine(result);{{/returnType}}
}
catch (Exception e)
{
Debug.Print("Exception when calling {{classname}}.{{operationId}}: " + e.Message );
}
{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}}
}
}
}
```
<a name="documentation-for-api-endpoints"></a>
## Documentation for API Endpoints
All URIs are relative to *{{{basePath}}}*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{{summary}}}{{/summary}}
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
<a name="documentation-for-models"></a>
## Documentation for Models
{{#modelPackage}}
{{#models}}{{#model}} - [{{{modelPackage}}}.{{{classname}}}]({{modelDocPath}}{{{classname}}}.md)
{{/model}}{{/models}}
{{/modelPackage}}
{{^modelPackage}}
No model defined in this package
{{/modelPackage}}
<a name="documentation-for-authorization"></a>
## Documentation for Authorization
{{^authMethods}}
All endpoints do not require authorization.
{{/authMethods}}
{{#authMethods}}
{{#last}}
Authentication schemes defined for the API:
{{/last}}
{{/authMethods}}
{{#authMethods}}
<a name="{{name}}"></a>
### {{name}}
{{#isApiKey}}- **Type**: API key
- **API key parameter name**: {{keyParamName}}
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
{{/isApiKey}}
{{#isBasic}}- **Type**: HTTP basic authentication
{{/isBasic}}
{{#isOAuth}}- **Type**: OAuth
- **Flow**: {{flow}}
- **Authorization URL**: {{authorizationUrl}}
- **Scopes**: {{^scopes}}N/A{{/scopes}}
{{#scopes}} - {{scope}}: {{description}}
{{/scopes}}
{{/isOAuth}}
{{/authMethods}}

View File

@ -0,0 +1,137 @@
{{>partial_header}}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace {{packageName}}.Client
{
public class ReadOnlyDictionary<T, K> : IDictionary<T, K>
{
private IDictionary<T, K> _dictionaryImplementation;
public IEnumerator<KeyValuePair<T, K>> GetEnumerator()
{
return _dictionaryImplementation.GetEnumerator();
}
public ReadOnlyDictionary()
{
_dictionaryImplementation = new Dictionary<T, K>();
}
public ReadOnlyDictionary(IDictionary<T, K> dictionaryImplementation)
{
if (dictionaryImplementation == null) throw new ArgumentNullException("dictionaryImplementation");
_dictionaryImplementation = dictionaryImplementation;
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable) _dictionaryImplementation).GetEnumerator();
}
public void Add(KeyValuePair<T, K> item)
{
throw new ReadonlyOperationException("This instance is readonly.");
}
public void Clear()
{
throw new ReadonlyOperationException("This instance is readonly.");
}
public bool Contains(KeyValuePair<T, K> item)
{
return _dictionaryImplementation.Contains(item);
}
public void CopyTo(KeyValuePair<T, K>[] array, int arrayIndex)
{
_dictionaryImplementation.CopyTo(array, arrayIndex);
}
public bool Remove(KeyValuePair<T, K> item)
{
throw new ReadonlyOperationException("This instance is readonly.");
}
public int Count
{
get { return _dictionaryImplementation.Count; }
}
public bool IsReadOnly
{
get { return true; }
}
public void Add(T key, K value)
{
throw new ReadonlyOperationException("This instance is readonly.");
}
public bool ContainsKey(T key)
{
return _dictionaryImplementation.ContainsKey(key);
}
public bool Remove(T key)
{
throw new ReadonlyOperationException("This instance is readonly.");
}
public bool TryGetValue(T key, out K value)
{
return _dictionaryImplementation.TryGetValue(key, out value);
}
public K this[T key]
{
get { return _dictionaryImplementation[key]; }
set
{
throw new ReadonlyOperationException("This instance is readonly.");
}
}
public ICollection<T> Keys
{
get { return _dictionaryImplementation.Keys; }
}
public ICollection<K> Values
{
get { return _dictionaryImplementation.Values; }
}
}
[Serializable]
public class ReadonlyOperationException : Exception
{
//
// For guidelines regarding the creation of new exception types, see
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp
// and
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp
//
public ReadonlyOperationException()
{
}
public ReadonlyOperationException(string message) : base(message)
{
}
public ReadonlyOperationException(string message, Exception inner) : base(message, inner)
{
}
protected ReadonlyOperationException(
SerializationInfo info,
StreamingContext context) : base(info, context)
{
}
}
}

View File

@ -0,0 +1,66 @@
{{>partial_header}}
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
namespace {{packageName}}.Client
{
/// <summary>
/// A container for generalized request inputs. This type allows consumers to extend the request functionality
/// by abstracting away from the default (built-in) request framework (e.g. RestSharp).
/// </summary>
public class RequestOptions
{
/// <summary>
/// Parameters to be bound to path parts of the Request's URL
/// </summary>
public Dictionary<String, String> PathParameters { get; set; }
/// <summary>
/// Query parameters to be applied to the request.
/// Keys may have 1 or more values associated.
/// </summary>
public Multimap<String, String> QueryParameters { get; set; }
/// <summary>
/// Header parameters to be applied to to the request.
/// Keys may have 1 or more values associated.
/// </summary>
public Multimap<String, String> HeaderParameters { get; set; }
/// <summary>
/// Form parameters to be sent along with the request.
/// </summary>
public Dictionary<String, String> FormParameters { get; set; }
/// <summary>
/// File parameters to be sent along with the request.
/// </summary>
public Dictionary<String, Stream> FileParameters { get; set; }
/// <summary>
/// Cookies to be sent along with the request.
/// </summary>
public List<Cookie> Cookies { get; set; }
/// <summary>
/// Any data associated with a request body.
/// </summary>
public Object Data { get; set; }
/// <summary>
/// Constructs a new instance of <see cref="RequestOptions"/>
/// </summary>
public RequestOptions()
{
PathParameters = new Dictionary<string, string>();
QueryParameters = new Multimap<string, string>();
HeaderParameters = new Multimap<string, string>();
FormParameters = new Dictionary<string, string>();
FileParameters = new Dictionary<String, Stream>();
Cookies = new List<Cookie>();
}
}
}

View File

@ -0,0 +1,27 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio {{^netStandard}}2012{{/netStandard}}{{#netStandard}}14{{/netStandard}}
VisualStudioVersion = {{^netStandard}}12.0.0.0{{/netStandard}}{{#netStandard}}14.0.25420.1{{/netStandard}}
MinimumVisualStudioVersion = {{^netStandard}}10.0.0.1{{/netStandard}}{{#netStandard}}10.0.40219.1{{/netStandard}}
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "{{packageName}}", "src\{{packageName}}\{{packageName}}.csproj", "{{packageGuid}}"
EndProject
{{^excludeTests}}Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "{{testPackageName}}", "src\{{testPackageName}}\{{testPackageName}}.csproj", "{19F1DEBC-DE5E-4517-8062-F000CD499087}"
EndProject
{{/excludeTests}}Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{{packageGuid}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{{packageGuid}}.Debug|Any CPU.Build.0 = Debug|Any CPU
{{packageGuid}}.Release|Any CPU.ActiveCfg = Release|Any CPU
{{packageGuid}}.Release|Any CPU.Build.0 = Release|Any CPU
{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
{{#appName}}
{{{appName}}}
{{/appName}}
{{#appDescription}}
{{{appDescription}}}
{{/appDescription}}
{{#version}}OpenAPI spec version: {{{version}}}{{/version}}
{{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
-->
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{19F1DEBC-DE5E-4517-8062-F000CD499087}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>{{testPackageName}}</RootNamespace>
<AssemblyName>{{testPackageName}}</AssemblyName>
{{^supportsUWP}}
<TargetFrameworkVersion>{{targetFramework}}</TargetFrameworkVersion>
{{/supportsUWP}}
{{#supportsUWP}}
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
{{/supportsUWP}}
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
<Reference Include="Newtonsoft.Json">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\Newtonsoft.Json.10.0.3\lib\{{targetFrameworkNuget}}\Newtonsoft.Json.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\Newtonsoft.Json.10.0.3\lib\{{targetFrameworkNuget}}\Newtonsoft.Json.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\Newtonsoft.Json.10.0.3\lib\{{targetFrameworkNuget}}\Newtonsoft.Json.dll</HintPath>
<HintPath Condition="Exists('{{binRelativePath}}')">{{binRelativePath}}\Newtonsoft.Json.10.0.3\lib\{{targetFrameworkNuget}}\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="JsonSubTypes">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\JsonSubTypes.1.2.0\lib\{{targetFrameworkNuget}}\JsonSubTypes.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\JsonSubTypes.1.2.0\lib\{{targetFrameworkNuget}}\JsonSubTypes.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\JsonSubTypes.1.2.0\lib\{{targetFrameworkNuget}}\JsonSubTypes.dll</HintPath>
<HintPath Condition="Exists('{{binRelativePath}}')">{{binRelativePath}}\JsonSubTypes.1.2.0\lib\{{targetFrameworkNuget}}\JsonSubTypes.dll</HintPath>
</Reference>
<Reference Include="RestSharp">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\RestSharp.105.1.0\lib\{{#isNet40}}net4{{/isNet40}}{{^isNet40}}{{targetFrameworkNuget}}{{/isNet40}}\RestSharp.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\RestSharp.105.1.0\lib\{{#isNet40}}net4{{/isNet40}}{{^isNet40}}{{targetFrameworkNuget}}{{/isNet40}}\RestSharp.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\RestSharp.105.1.0\lib\{{#isNet40}}net4{{/isNet40}}{{^isNet40}}{{targetFrameworkNuget}}{{/isNet40}}\RestSharp.dll</HintPath>
<HintPath Condition="Exists('{{binRelativePath}}')">{{binRelativePath}}\RestSharp.105.1.0\lib\{{#isNet40}}net4{{/isNet40}}{{^isNet40}}{{targetFrameworkNuget}}{{/isNet40}}\RestSharp.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<HintPath Condition="Exists('$(SolutionDir)\packages')">$(SolutionDir)\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
<HintPath Condition="Exists('..\packages')">..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
<HintPath Condition="Exists('..\..\packages')">..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
<HintPath Condition="Exists('{{binRelativePath}}')">{{binRelativePath}}\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="**\*.cs"
Exclude="obj\**"/>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MsBuildToolsPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\{{packageName}}\{{packageName}}.csproj">
<Project>{{packageGuid}}</Project>
<Name>{{packageName}}</Name>
</ProjectReference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,480 @@
{{>partial_header}}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Net.Mime;
using {{packageName}}.Client;
{{#hasImport}}using {{packageName}}.{{modelPackage}};
{{/hasImport}}
namespace {{packageName}}.{{apiPackage}}
{
{{#operations}}
/// <summary>
/// Represents a collection of functions to interact with the API endpoints
/// </summary>
{{>visibility}} interface {{interfacePrefix}}{{classname}}Sync : IApiAccessor
{
#region Synchronous Operations
{{#operation}}
/// <summary>
/// {{summary}}
/// </summary>
/// <remarks>
/// {{notes}}
/// </remarks>
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
{{/allParams}}/// <returns>{{#returnType}}{{returnType}}{{/returnType}}</returns>
{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}} ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
/// <summary>
/// {{summary}}
/// </summary>
/// <remarks>
/// {{notes}}
/// </remarks>
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
{{/allParams}}/// <returns>ApiResponse of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object(void){{/returnType}}</returns>
ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> {{operationId}}WithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/operation}}
#endregion Synchronous Operations
}
{{#supportsAsync}}
/// <summary>
/// Represents a collection of functions to interact with the API endpoints
/// </summary>
{{>visibility}} interface {{interfacePrefix}}{{classname}}Async : IApiAccessor
{
#region Asynchronous Operations
{{#operation}}
/// <summary>
/// {{summary}}
/// </summary>
/// <remarks>
/// {{notes}}
/// </remarks>
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
{{/allParams}}/// <returns>Task of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}</returns>
{{#returnType}}System.Threading.Tasks.Task<{{{returnType}}}>{{/returnType}}{{^returnType}}System.Threading.Tasks.Task{{/returnType}} {{operationId}}Async ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
/// <summary>
/// {{summary}}
/// </summary>
/// <remarks>
/// {{notes}}
/// </remarks>
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
{{/allParams}}/// <returns>Task of ApiResponse{{#returnType}} ({{returnType}}){{/returnType}}</returns>
System.Threading.Tasks.Task<ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>> {{operationId}}AsyncWithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/operation}}
#endregion Asynchronous Operations
}
{{/supportsAsync}}
{{>visibility}} interface {{interfacePrefix}}{{classname}} : {{interfacePrefix}}{{classname}}Sync{{#supportsAsync}}, {{interfacePrefix}}{{classname}}Async{{/supportsAsync}}
{
}
/// <summary>
/// Represents a collection of functions to interact with the API endpoints
/// </summary>
{{>visibility}} partial class {{classname}} : {{interfacePrefix}}{{classname}}
{
private {{packageName}}.Client.ExceptionFactory _exceptionFactory = (name, response) => null;
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
/// </summary>
/// <returns></returns>
public {{classname}}() : this((string) null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
/// </summary>
/// <returns></returns>
public {{classname}}(String basePath)
{
this.Configuration = {{packageName}}.Client.Configuration.MergeConfigurations(
{{packageName}}.Client.GlobalConfiguration.Instance,
new {{packageName}}.Client.Configuration { BasePath = basePath }
);
this.Client = new {{packageName}}.Client.ApiClient(this.Configuration.BasePath);
this.AsynchronousClient = new {{packageName}}.Client.ApiClient(this.Configuration.BasePath);
this.ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
}
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}"/> class
/// using Configuration object
/// </summary>
/// <param name="configuration">An instance of Configuration</param>
/// <returns></returns>
public {{classname}}({{packageName}}.Client.Configuration configuration)
{
if (configuration == null) throw new ArgumentNullException("configuration");
this.Configuration = {{packageName}}.Client.Configuration.MergeConfigurations(
{{packageName}}.Client.GlobalConfiguration.Instance,
configuration
);
this.Client = new {{packageName}}.Client.ApiClient(this.Configuration.BasePath);
this.AsynchronousClient = new {{packageName}}.Client.ApiClient(this.Configuration.BasePath);
ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
}
/// <summary>
/// Initializes a new instance of the <see cref="PetApi"/> class
/// using a Configuration object and client instance.
/// </summary>
/// <param name="client">The client interface for synchronous API access.</param>{{#supportsAsync}}
/// <param name="asyncClient">The client interface for asynchronous API access.</param>{{/supportsAsync}}
/// <param name="configuration">The configuration object.</param>
public {{classname}}({{packageName}}.Client.ISynchronousClient client,{{#supportsAsync}}{{packageName}}.Client.IAsynchronousClient asyncClient,{{/supportsAsync}} {{packageName}}.Client.IReadableConfiguration configuration)
{
if(client == null) throw new ArgumentNullException("client");
{{#supportsAsync}}
if(asyncClient == null) throw new ArgumentNullException("asyncClient");
{{/supportsAsync}}
if(configuration == null) throw new ArgumentNullException("configuration");
this.Client = client;
{{#supportsAsync}}
this.AsynchronousClient = asyncClient;
{{/supportsAsync}}
this.Configuration = configuration;
this.ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
}
{{#supportsAsync}}
/// <summary>
/// The client for accessing this underlying API asynchronously.
/// </summary>
public {{packageName}}.Client.IAsynchronousClient AsynchronousClient { get; set; }
{{/supportsAsync}}
/// <summary>
/// The client for accessing this underlying API synchronously.
/// </summary>
public {{packageName}}.Client.ISynchronousClient Client { get; set; }
/// <summary>
/// Gets the base path of the API client.
/// </summary>
/// <value>The base path</value>
public String GetBasePath()
{
return this.Configuration.BasePath;
}
/// <summary>
/// Gets or sets the configuration object
/// </summary>
/// <value>An instance of the Configuration</value>
public {{packageName}}.Client.IReadableConfiguration Configuration {get; set;}
/// <summary>
/// Provides a factory method hook for the creation of exceptions.
/// </summary>
public {{packageName}}.Client.ExceptionFactory ExceptionFactory
{
get
{
if (_exceptionFactory != null && _exceptionFactory.GetInvocationList().Length > 1)
{
throw new InvalidOperationException("Multicast delegate for ExceptionFactory is unsupported.");
}
return _exceptionFactory;
}
set { _exceptionFactory = value; }
}
{{#operation}}
/// <summary>
/// {{summary}} {{notes}}
/// </summary>
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
{{/allParams}}/// <returns>{{#returnType}}{{returnType}}{{/returnType}}</returns>
public {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}} ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{
{{#returnType}}{{packageName}}.Client.ApiResponse<{{{returnType}}}> localVarResponse = {{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
return localVarResponse.Data;{{/returnType}}{{^returnType}}{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{/returnType}}
}
/// <summary>
/// {{summary}} {{notes}}
/// </summary>
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
{{/allParams}}/// <returns>ApiResponse of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object(void){{/returnType}}</returns>
public {{packageName}}.Client.ApiResponse<{{#returnType}} {{{returnType}}} {{/returnType}}{{^returnType}}Object{{/returnType}}> {{operationId}}WithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{
{{#allParams}}
{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null)
throw new {{packageName}}.Client.ApiException(400, "Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}");
{{/required}}
{{/allParams}}
{{packageName}}.Client.RequestOptions requestOptions = new {{packageName}}.Client.RequestOptions();
String[] @contentTypes = new String[] {
{{#consumes}}
"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}
{{/consumes}}
};
// to determine the Accept header
String[] @accepts = new String[] {
{{#produces}}
"{{{mediaType}}}"{{#hasMore}},{{/hasMore}}
{{/produces}}
};
foreach (var contentType in @contentTypes)
requestOptions.HeaderParameters.Add("Content-Type", contentType);
foreach (var accept in @accepts)
requestOptions.HeaderParameters.Add("Accept", accept);
{{#pathParams}}
if ({{paramName}} != null)
requestOptions.PathParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // path parameter
{{/pathParams}}
{{#queryParams}}
if ({{paramName}} != null)
{
foreach (var kvp in {{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}))
{
foreach (var value in kvp.Value)
{
requestOptions.QueryParameters.Add(kvp.Key, value);
}
}
}
{{/queryParams}}
{{#headerParams}}
if ({{paramName}} != null)
requestOptions.HeaderParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // header parameter
{{/headerParams}}
{{#formParams}}
if ({{paramName}} != null)
{
{{#isFile}}
requestOptions.FileParameters.Add("{{baseName}}", {{paramName}});
{{/isFile}}
{{^isFile}}
requestOptions.FormParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // form parameter
{{/isFile}}
}
{{/formParams}}
{{#bodyParam}}
requestOptions.Data = {{paramName}};
{{/bodyParam}}
{{#authMethods}}
// authentication ({{name}}) required
{{#isApiKey}}
{{#isKeyInHeader}}
if (!String.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
{
requestOptions.HeaderParameters.Add("{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}"));
}
{{/isKeyInHeader}}
{{#isKeyInQuery}}
if (!String.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
{
foreach (var kvp in {{packageName}}.Client.ClientUtils.ParameterToMultiMap("", "{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
{
foreach (var value in kvp.Value)
{
requestOptions.QueryParameters.Add(kvp.Key, value);
}
}
}
{{/isKeyInQuery}}
{{/isApiKey}}
{{#isBasic}}
// http basic authentication required
if (!String.IsNullOrEmpty(this.Configuration.Username) || !String.IsNullOrEmpty(this.Configuration.Password))
{
requestOptions.HeaderParameters.Add("Authorization", "Basic " + {{packageName}}.Client.ClientUtils.Base64Encode(this.Configuration.Username + ":" + this.Configuration.Password));
}
{{/isBasic}}
{{#isOAuth}}
// oauth required
if (!String.IsNullOrEmpty(this.Configuration.AccessToken))
{
requestOptions.HeaderParameters.Add("Authorization", "Bearer " + this.Configuration.AccessToken);
}
{{/isOAuth}}
{{/authMethods}}
// make the HTTP request
var response = this.Client.{{#lambda.titlecase}}{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}{{/lambda.titlecase}}<{{#returnType}} {{{returnType}}} {{/returnType}}{{^returnType}}Object{{/returnType}}>("{{{path}}}", requestOptions, this.Configuration);
if (this.ExceptionFactory != null)
{
Exception exception = this.ExceptionFactory("{{operationId}}", response);
if (exception != null) throw exception;
}
return response;
}
{{#supportsAsync}}
/// <summary>
/// {{summary}} {{notes}}
/// </summary>
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
{{/allParams}}/// <returns>Task of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}</returns>
{{#returnType}}public async System.Threading.Tasks.Task<{{{returnType}}}>{{/returnType}}{{^returnType}}public async System.Threading.Tasks.Task{{/returnType}} {{operationId}}Async ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{
{{#returnType}}{{packageName}}.Client.ApiResponse<{{{returnType}}}> localVarResponse = await {{operationId}}AsyncWithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
return localVarResponse.Data;{{/returnType}}{{^returnType}}await {{operationId}}AsyncWithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{/returnType}}
}
/// <summary>
/// {{summary}} {{notes}}
/// </summary>
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
{{/allParams}}/// <returns>Task of ApiResponse{{#returnType}} ({{returnType}}){{/returnType}}</returns>
public async System.Threading.Tasks.Task<{{packageName}}.Client.ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>> {{operationId}}AsyncWithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{
{{#allParams}}
{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null)
throw new {{packageName}}.Client.ApiException(400, "Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}");
{{/required}}
{{/allParams}}
{{packageName}}.Client.RequestOptions requestOptions = new {{packageName}}.Client.RequestOptions();
String[] @contentTypes = new String[] {
{{#consumes}}
"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}
{{/consumes}}
};
// to determine the Accept header
String[] @accepts = new String[] {
{{#produces}}
"{{{mediaType}}}"{{#hasMore}},{{/hasMore}}
{{/produces}}
};
foreach (var contentType in @contentTypes)
requestOptions.HeaderParameters.Add("Content-Type", contentType);
foreach (var accept in @accepts)
requestOptions.HeaderParameters.Add("Accept", accept);
{{#pathParams}}
if ({{paramName}} != null)
requestOptions.PathParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // path parameter
{{/pathParams}}
{{#queryParams}}
if ({{paramName}} != null)
{
foreach (var kvp in {{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}))
{
foreach (var value in kvp.Value)
{
requestOptions.QueryParameters.Add(kvp.Key, value);
}
}
}
{{/queryParams}}
{{#headerParams}}
if ({{paramName}} != null)
requestOptions.HeaderParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // header parameter
{{/headerParams}}
{{#formParams}}
if ({{paramName}} != null)
{
{{#isFile}}
requestOptions.FileParameters.Add("{{baseName}}", {{paramName}});
{{/isFile}}
{{^isFile}}
requestOptions.FormParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // form parameter
{{/isFile}}
}
{{/formParams}}
{{#bodyParam}}
requestOptions.Data = {{paramName}};
{{/bodyParam}}
{{#authMethods}}
// authentication ({{name}}) required
{{#isApiKey}}
{{#isKeyInHeader}}
if (!String.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
{
requestOptions.HeaderParameters.Add("{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}"));
}
{{/isKeyInHeader}}
{{#isKeyInQuery}}
if (!String.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
{
foreach (var kvp in {{packageName}}.Client.ClientUtils.ParameterToMultiMap("", "{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
{
foreach (var value in kvp.Value)
{
requestOptions.QueryParameters.Add(kvp.Key, value);
}
}
}
{{/isKeyInQuery}}
{{/isApiKey}}
{{#isBasic}}
// http basic authentication required
if (!String.IsNullOrEmpty(this.Configuration.Username) || !String.IsNullOrEmpty(this.Configuration.Password))
{
requestOptions.HeaderParameters.Add("Authorization", "Basic " + {{packageName}}.Client.ClientUtils.Base64Encode(this.Configuration.Username + ":" + this.Configuration.Password));
}
{{/isBasic}}
{{#isOAuth}}
// oauth required
if (!String.IsNullOrEmpty(this.Configuration.AccessToken))
{
requestOptions.HeaderParameters.Add("Authorization", "Bearer " + this.Configuration.AccessToken);
}
{{/isOAuth}}
{{/authMethods}}
// make the HTTP request
var response = await this.AsynchronousClient.{{#lambda.titlecase}}{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}{{/lambda.titlecase}}Async<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>("{{{path}}}", requestOptions, this.Configuration);
if (this.ExceptionFactory != null)
{
Exception exception = this.ExceptionFactory("{{operationId}}", response);
if (exception != null) throw exception;
}
return response;
}
{{/supportsAsync}}
{{/operation}}
}
{{/operations}}
}

View File

@ -0,0 +1,105 @@
# {{packageName}}.{{apiPackage}}.{{classname}}{{#description}}
{{description}}{{/description}}
All URIs are relative to *{{{basePath}}}*
Method | HTTP request | Description
------------- | ------------- | -------------
{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
{{/operation}}{{/operations}}
{{#operations}}
{{#operation}}
<a name="{{{operationIdLowerCase}}}"></a>
# **{{{operationId}}}**
> {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}} ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{{{summary}}}{{#notes}}
{{{notes}}}{{/notes}}
### Example
```csharp
using System;
using System.Diagnostics;
using {{packageName}}.{{apiPackage}};
using {{packageName}}.Client;
using {{packageName}}.{{modelPackage}};
namespace Example
{
public class {{operationId}}Example
{
public void main()
{
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasic}}
// Configure HTTP basic authorization: {{{name}}}
Configuration.Default.Username = "YOUR_USERNAME";
Configuration.Default.Password = "YOUR_PASSWORD";
{{/isBasic}}
{{#isApiKey}}
// Configure API key authorization: {{{name}}}
Configuration.Default.AddApiKey("{{{keyParamName}}}", "YOUR_API_KEY");
// Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
// Configuration.Default.AddApiKeyPrefix("{{{keyParamName}}}", "Bearer");
{{/isApiKey}}
{{#isOAuth}}
// Configure OAuth2 access token for authorization: {{{name}}}
Configuration.Default.AccessToken = "YOUR_ACCESS_TOKEN";
{{/isOAuth}}
{{/authMethods}}
{{/hasAuthMethods}}
var apiInstance = new {{classname}}();
{{#allParams}}
{{#isPrimitiveType}}
var {{paramName}} = {{{example}}}; // {{{dataType}}} | {{{description}}}{{^required}} (optional) {{/required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}
{{/isPrimitiveType}}
{{^isPrimitiveType}}
var {{paramName}} = new {{{dataType}}}(); // {{{dataType}}} | {{{description}}}{{^required}} (optional) {{/required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}
{{/isPrimitiveType}}
{{/allParams}}
try
{
{{#summary}}
// {{{.}}}
{{/summary}}
{{#returnType}}{{returnType}} result = {{/returnType}}apiInstance.{{{operationId}}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{#returnType}}
Debug.WriteLine(result);{{/returnType}}
}
catch (Exception e)
{
Debug.Print("Exception when calling {{classname}}.{{operationId}}: " + e.Message );
}
}
}
}
```
### Parameters
{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}}
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}}
{{#allParams}} **{{paramName}}** | {{#isFile}}**{{dataType}}**{{/isFile}}{{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{^isFile}}[**{{dataType}}**]({{#isContainer}}{{baseType}}{{/isContainer}}{{^isContainer}}{{dataType}}{{/isContainer}}.md){{/isFile}}{{/isPrimitiveType}}| {{description}} | {{^required}}[optional] {{/required}}{{#defaultValue}}[default to {{defaultValue}}]{{/defaultValue}}
{{/allParams}}
### Return type
{{#returnType}}{{#returnTypeIsPrimitive}}**{{{returnType}}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}[**{{{returnType}}}**]({{returnBaseType}}.md){{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}void (empty response body){{/returnType}}
### Authorization
{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{{name}}}](../README.md#{{{name}}}){{^-last}}, {{/-last}}{{/authMethods}}
### HTTP request headers
- **Content-Type**: {{#consumes}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}}
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
{{/operation}}
{{/operations}}

View File

@ -0,0 +1,75 @@
{{>partial_header}}
using System;
using System.IO;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using RestSharp;
using NUnit.Framework;
using {{packageName}}.Client;
using {{packageName}}.{{apiPackage}};
{{#hasImport}}using {{packageName}}.{{modelPackage}};
{{/hasImport}}
namespace {{packageName}}.Test
{
/// <summary>
/// Class for testing {{classname}}
/// </summary>
/// <remarks>
/// This file is automatically generated by OpenAPI Generator (https://openapi-generator.tech).
/// Please update the test case below to test the API endpoint.
/// </remarks>
[TestFixture]
public class {{classname}}Tests
{
private {{classname}} instance;
/// <summary>
/// Setup before each unit test
/// </summary>
[SetUp]
public void Init()
{
instance = new {{classname}}();
}
/// <summary>
/// Clean up after each unit test
/// </summary>
[TearDown]
public void Cleanup()
{
}
/// <summary>
/// Test an instance of {{classname}}
/// </summary>
[Test]
public void {{operationId}}InstanceTest()
{
// TODO uncomment below to test 'IsInstanceOfType' {{classname}}
//Assert.IsInstanceOfType(typeof({{classname}}), instance, "instance is a {{classname}}");
}
{{#operations}}{{#operation}}
/// <summary>
/// Test {{operationId}}
/// </summary>
[Test]
public void {{operationId}}Test()
{
// TODO uncomment below to test the method and replace null with proper value
{{#allParams}}
//{{{dataType}}} {{paramName}} = null;
{{/allParams}}
//{{#returnType}}var response = {{/returnType}}instance.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{#returnType}}//Assert.IsInstanceOf<{{{returnType}}}> (response, "response is {{{returnType}}}");{{/returnType}}
}
{{/operation}}{{/operations}}
}
}

View File

@ -0,0 +1,78 @@
#!/usr/bin/env bash
#
# Generated by: https://github.com/openapitools/openapi-generator.git
#
frameworkVersion={{targetFrameworkNuget}}
# sdk must match installed framworks under PREFIX/lib/mono/[value]
sdk={{x-mcs-sdk}}
# langversion refers to C# language features. see man mcs for details.
langversion=${sdk}
nuget_cmd=nuget
# Match against our known SDK possibilities
case "${sdk}" in
4)
langversion=4
;;
4.5*)
langversion=5
;;
4.6*)
langversion=6
;;
4.7*)
langversion=7 # ignoring 7.1 for now.
;;
*)
langversion=6
;;
esac
echo "[INFO] Target framework: ${frameworkVersion}"
if ! type nuget &>/dev/null; then
echo "[INFO] Download nuget and packages"
wget -nc https://dist.nuget.org/win-x86-commandline/latest/nuget.exe;
nuget_cmd="mono nuget.exe"
fi
mozroots --import --sync
${nuget_cmd} install src/{{packageName}}/packages.config -o packages;
echo "[INFO] Copy DLLs to the 'bin' folder"
mkdir -p bin;
cp packages/Newtonsoft.Json.10.0.3/lib/{{targetFrameworkNuget}}/Newtonsoft.Json.dll bin/Newtonsoft.Json.dll;
cp packages/RestSharp.105.1.0/lib/{{#isNet40}}net4{{/isNet40}}{{^isNet40}}{{targetFrameworkNuget}}{{/isNet40}}/RestSharp.dll bin/RestSharp.dll;
cp packages/JsonSubTypes.1.2.0/lib/{{targetFrameworkNuget}}/JsonSubTypes.dll bin/JsonSubTypes.dll
{{#generatePropertyChanged}}
cp packages/Fody.1.29.4/Fody.dll bin/Fody.dll
cp packages/PropertyChanged.Fody.1.51.3/PropertyChanged.Fody.dll bin/PropertyChanged.Fody.dll
cp packages/PropertyChanged.Fody.1.51.3/Lib/dotnet/PropertyChanged.dll bin/PropertyChanged.dll
{{/generatePropertyChanged}}
echo "[INFO] Run 'mcs' to build bin/{{{packageName}}}.dll"
mcs -langversion:${langversion} -sdk:${sdk} -r:bin/Newtonsoft.Json.dll,bin/JsonSubTypes.dll,\
{{#generatePropertyChanged}}
bin/Fody.dll,\
bin/PropertyChanged.Fody.dll,\
bin/PropertyChanged.dll,\
{{/generatePropertyChanged}}
bin/RestSharp.dll,\
System.ComponentModel.DataAnnotations.dll,\
System.Runtime.Serialization.dll \
-target:library \
-out:bin/{{packageName}}.dll \
-recurse:'src/{{packageName}}/*.cs' \
-doc:bin/{{packageName}}.xml \
-platform:anycpu
if [ $? -ne 0 ]
then
echo "[ERROR] Compilation failed with exit code $?"
exit 1
else
echo "[INFO] bin/{{{packageName}}}.dll was created successfully"
fi

View File

@ -0,0 +1,27 @@
:: Generated by: https://github.com/openapitools/openapi-generator.git
::
@echo off
{{#supportsAsync}}
SET CSCPATH=%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319
{{/supportsAsync}}
{{^supportsAsync}}
SET CSCPATH=%SYSTEMROOT%\Microsoft.NET\Framework\v3.5
{{/supportsAsync}}
if not exist ".\nuget.exe" powershell -Command "(new-object System.Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '.\nuget.exe')"
.\nuget.exe install src\{{packageName}}\packages.config -o packages
if not exist ".\bin" mkdir bin
copy packages\Newtonsoft.Json.10.0.3\lib\{{targetFrameworkNuget}}\Newtonsoft.Json.dll bin\Newtonsoft.Json.dll
copy packages\JsonSubTypes.1.2.0\lib\{{targetFrameworkNuget}}\JsonSubTypes.dll bin\JsonSubTypes.dll
copy packages\RestSharp.105.1.0\lib\{{#isNet40}}net4{{/isNet40}}{{^isNet40}}{{targetFrameworkNuget}}{{/isNet40}}\RestSharp.dll bin\RestSharp.dll
{{#generatePropertyChanged}}
copy packages\Fody.1.29.4\Fody.dll bin\Fody.dll
copy packages\PropertyChanged.Fody.1.51.3\PropertyChanged.Fody.dll bin\PropertyChanged.Fody.dll
copy packages\PropertyChanged.Fody.1.51.3\Lib\dotnet\PropertyChanged.dll bin\PropertyChanged.dll
{{/generatePropertyChanged}}
%CSCPATH%\csc /reference:bin\Newtonsoft.Json.dll;bin\JsonSubTypes.dll;bin\RestSharp.dll;System.ComponentModel.DataAnnotations.dll {{#generatePropertyChanged}}/r:bin\Fody.dll;bin\PropertyChanged.Fody.dll;bin\PropertyChanged.dll{{/generatePropertyChanged}} /target:library /out:bin\{{packageName}}.dll /recurse:src\{{packageName}}\*.cs /doc:bin\{{packageName}}.xml

View File

@ -0,0 +1,20 @@
/// <summary>
/// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
/// </summary>
{{#description}}
/// <value>{{description}}</value>
{{/description}}
[JsonConverter(typeof(StringEnumConverter))]
{{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}
{
{{#allowableValues}}
{{#enumVars}}
/// <summary>
/// Enum {{name}} for {{{value}}}
/// </summary>
[EnumMember(Value = {{#isLong}}"{{/isLong}}{{#isInteger}}"{{/isInteger}}{{#isFloat}}"{{/isFloat}}{{#isDouble}}"{{/isDouble}}{{{value}}}{{#isLong}}"{{/isLong}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isFloat}}"{{/isFloat}})]
{{name}}{{#isLong}} = {{{value}}}{{/isLong}}{{#isInteger}} = {{{value}}}{{/isInteger}}{{^isInteger}} = {{-index}}{{/isInteger}}{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
}

View File

@ -0,0 +1,52 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update"
git_user_id=$1
git_repo_id=$2
release_note=$3
if [ "$git_user_id" = "" ]; then
git_user_id="{{{gitUserId}}}"
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
fi
if [ "$git_repo_id" = "" ]; then
git_repo_id="{{{gitRepoId}}}"
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
fi
if [ "$release_note" = "" ]; then
release_note="{{{releaseNote}}}"
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
fi
# Initialize the local directory as a Git repository
git init
# Adds the files in the local repository and stages them for commit.
git add .
# Commits the tracked changes and prepares them to be pushed to a remote repository.
git commit -m "$release_note"
# Sets the new remote
git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
fi
fi
git pull origin master
# Pushes (Forces) the changes in the local repository up to the remote repository
echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
git push origin master 2>&1 | grep -v 'To https'

View File

@ -0,0 +1,186 @@
# Ref: https://gist.github.com/kmorcinek/2710267
# Download this file using PowerShell v3 under Windows with the following comand
# Invoke-WebRequest https://gist.githubusercontent.com/kmorcinek/2710267/raw/ -OutFile .gitignore
# User-specific files
*.suo
*.user
*.sln.docstates
./nuget
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# OS generated files #
.DS_Store*
ehthumbs.db
Icon?
Thumbs.db
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
modulesbin/
tempbin/
# EPiServer Site file (VPP)
AppData/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# vim
*.txt~
*.swp
*.swo
# svn
.svn
# SQL Server files
**/App_Data/*.mdf
**/App_Data/*.ldf
**/App_Data/*.sdf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store
# SASS Compiler cache
.sass-cache
# Visual Studio 2014 CTP
**/*.sln.ide

View File

@ -0,0 +1,39 @@
{{>partial_header}}
using System;
using System.Linq;
using System.IO;
using System.Text;
{{^netStandard}}
using System.Text.RegularExpressions;
{{/netStandard}}
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
{{#models}}
{{#model}}
{{#discriminator}}
using JsonSubTypes;
{{/discriminator}}
{{/model}}
{{/models}}
{{^netStandard}}
{{#generatePropertyChanged}}
using PropertyChanged;
using System.ComponentModel;
{{/generatePropertyChanged}}
using System.ComponentModel.DataAnnotations;
{{/netStandard}}
using OpenAPIDateConverter = {{packageName}}.Client.OpenAPIDateConverter;
{{#models}}
{{#model}}
namespace {{packageName}}.{{modelPackage}}
{
{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{>modelGeneric}}{{/isEnum}}
{{/model}}
{{/models}}
}

View File

@ -0,0 +1,24 @@
/// <summary>
/// {{^description}}Defines {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
/// </summary>
{{#description}}
/// <value>{{description}}</value>
{{/description}}
{{#allowableValues}}{{#enumVars}}{{#-first}}{{#isString}}
[JsonConverter(typeof(StringEnumConverter))]
{{/isString}}{{/-first}}{{/enumVars}}{{/allowableValues}}
{{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}{{#vendorExtensions.x-enum-byte}}: byte{{/vendorExtensions.x-enum-byte}}
{
{{#allowableValues}}
{{#enumVars}}
/// <summary>
/// Enum {{name}} for value: {{{value}}}
/// </summary>
{{#isString}}
[EnumMember(Value = "{{{value}}}")]
{{/isString}}
{{name}}{{^isString}} = {{{value}}}{{/isString}}{{#isString}} = {{-index}}{{/isString}}{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
}{{! NOTE: This model's enumVars is modified to look like CodegenProperty}}

View File

@ -0,0 +1,306 @@
/// <summary>
/// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}}
/// </summary>
[DataContract]
{{#discriminator}}
[JsonConverter(typeof(JsonSubtypes), "{{{discriminatorName}}}")]{{#children}}
[JsonSubtypes.KnownSubType(typeof({{classname}}), "{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}")]{{/children}}
{{/discriminator}}
{{#generatePropertyChanged}}
[ImplementPropertyChanged]
{{/generatePropertyChanged}}
{{>visibility}} partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>{{^netStandard}}{{#validatable}}, IValidatableObject{{/validatable}}{{/netStandard}}
{
{{#vars}}
{{#items.isEnum}}
{{#items}}
{{^complexType}}
{{>modelInnerEnum}}
{{/complexType}}
{{/items}}
{{/items.isEnum}}
{{#isEnum}}
{{^complexType}}
{{>modelInnerEnum}}
{{/complexType}}
{{/isEnum}}
{{#isEnum}}
/// <summary>
/// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
/// </summary>
{{#description}}
/// <value>{{description}}</value>
{{/description}}
[DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})]
public {{#complexType}}{{{complexType}}}{{/complexType}}{{^complexType}}{{{datatypeWithEnum}}}{{/complexType}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}} {{name}} { get; set; }
{{/isEnum}}
{{/vars}}
{{#hasRequired}}
{{^hasOnlyReadOnly}}
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}" /> class.
/// </summary>
[JsonConstructorAttribute]
protected {{classname}}() { }
{{/hasOnlyReadOnly}}
{{/hasRequired}}
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}" /> class.
/// </summary>
{{#vars}}
{{^isReadOnly}}
/// <param name="{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}">{{#description}}{{description}}{{/description}}{{^description}}{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}{{/description}}{{#required}} (required){{/required}}{{#defaultValue}} (default to {{defaultValue}}){{/defaultValue}}.</param>
{{/isReadOnly}}
{{/vars}}
{{#hasOnlyReadOnly}}
[JsonConstructorAttribute]
{{/hasOnlyReadOnly}}
public {{classname}}({{#readWriteVars}}{{{datatypeWithEnum}}}{{#isEnum}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}}{{/isEnum}} {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} = {{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}default({{{datatypeWithEnum}}}{{#isEnum}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}}{{/isEnum}}){{/defaultValue}}{{^-last}}, {{/-last}}{{/readWriteVars}}){{#parent}} : base({{#parentVars}}{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}{{#hasMore}}, {{/hasMore}}{{/parentVars}}){{/parent}}
{
{{#vars}}
{{^isInherited}}
{{^isReadOnly}}
{{#required}}
// to ensure "{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}" is required (not null)
if ({{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} == null)
{
throw new InvalidDataException("{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} is a required property for {{classname}} and cannot be null");
}
else
{
this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
}
{{/required}}
{{/isReadOnly}}
{{/isInherited}}
{{/vars}}
{{#vars}}
{{^isInherited}}
{{^isReadOnly}}
{{^required}}
{{#defaultValue}}// use default value if no "{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}" provided
if ({{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} == null)
{
this.{{name}} = {{{defaultValue}}};
}
else
{
this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
}
{{/defaultValue}}
{{^defaultValue}}
this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
{{/defaultValue}}
{{/required}}
{{/isReadOnly}}
{{/isInherited}}
{{/vars}}
}
{{#vars}}
{{^isInherited}}
{{^isEnum}}
/// <summary>
/// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
/// </summary>{{#description}}
/// <value>{{description}}</value>{{/description}}
[DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})]{{#isDate}}
[JsonConverter(typeof(OpenAPIDateConverter))]{{/isDate}}
public {{{dataType}}} {{name}} { get; {{#isReadOnly}}private {{/isReadOnly}}set; }
{{/isEnum}}
{{/isInherited}}
{{/vars}}
/// <summary>
/// Returns the string presentation of the object
/// </summary>
/// <returns>String presentation of the object</returns>
public override string ToString()
{
var sb = new StringBuilder();
sb.Append("class {{classname}} {\n");
{{#parent}}
sb.Append(" ").Append(base.ToString().Replace("\n", "\n ")).Append("\n");
{{/parent}}
{{#vars}}
sb.Append(" {{name}}: ").Append({{name}}).Append("\n");
{{/vars}}
sb.Append("}\n");
return sb.ToString();
}
/// <summary>
/// Returns the JSON string presentation of the object
/// </summary>
/// <returns>JSON string presentation of the object</returns>
public {{#parent}}{{^isArrayModel}}{{^isMapModel}}override {{/isMapModel}}{{/isArrayModel}}{{/parent}}{{^parent}}virtual {{/parent}}string ToJson()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
/// <summary>
/// Returns true if objects are equal
/// </summary>
/// <param name="input">Object to be compared</param>
/// <returns>Boolean</returns>
public override bool Equals(object input)
{
return this.Equals(input as {{classname}});
}
/// <summary>
/// Returns true if {{classname}} instances are equal
/// </summary>
/// <param name="input">Instance of {{classname}} to be compared</param>
/// <returns>Boolean</returns>
public bool Equals({{classname}} input)
{
if (input == null)
return false;
return {{#vars}}{{#parent}}base.Equals(input) && {{/parent}}{{#isNotContainer}}
(
this.{{name}} == input.{{name}} ||
(this.{{name}} != null &&
this.{{name}}.Equals(input.{{name}}))
){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{^isNotContainer}}
(
this.{{name}} == input.{{name}} ||
this.{{name}} != null &&
this.{{name}}.SequenceEqual(input.{{name}})
){{#hasMore}} && {{/hasMore}}{{/isNotContainer}}{{/vars}}{{^vars}}{{#parent}}base.Equals(input){{/parent}}{{^parent}}false{{/parent}}{{/vars}};
}
/// <summary>
/// Gets the hash code
/// </summary>
/// <returns>Hash code</returns>
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
{{#parent}}
int hashCode = base.GetHashCode();
{{/parent}}
{{^parent}}
int hashCode = 41;
{{/parent}}
{{#vars}}
if (this.{{name}} != null)
hashCode = hashCode * 59 + this.{{name}}.GetHashCode();
{{/vars}}
return hashCode;
}
}
{{^netStandard}}
{{#generatePropertyChanged}}
/// <summary>
/// Property changed event handler
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Trigger when a property changed
/// </summary>
/// <param name="propertyName">Property Name</param>
public virtual void OnPropertyChanged(string propertyName)
{
// NOTE: property changed is handled via "code weaving" using Fody.
// Properties with setters are modified at compile time to notify of changes.
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
{{/generatePropertyChanged}}
{{#validatable}}
{{#discriminator}}
/// <summary>
/// To validate all properties of the instance
/// </summary>
/// <param name="validationContext">Validation context</param>
/// <returns>Validation Result</returns>
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{
return this.BaseValidate(validationContext);
}
/// <summary>
/// To validate all properties of the instance
/// </summary>
/// <param name="validationContext">Validation context</param>
/// <returns>Validation Result</returns>
protected IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> BaseValidate(ValidationContext validationContext)
{
{{/discriminator}}
{{^discriminator}}
/// <summary>
/// To validate all properties of the instance
/// </summary>
/// <param name="validationContext">Validation context</param>
/// <returns>Validation Result</returns>
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{
{{/discriminator}}
{{#parent}}
{{^isArrayModel}}
{{^isMapModel}}
foreach(var x in BaseValidate(validationContext)) yield return x;
{{/isMapModel}}
{{/isArrayModel}}
{{/parent}}
{{#vars}}
{{#hasValidation}}
{{#maxLength}}
// {{{name}}} ({{{dataType}}}) maxLength
if(this.{{{name}}} != null && this.{{{name}}}.Length > {{maxLength}})
{
yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, length must be less than {{maxLength}}.", new [] { "{{{name}}}" });
}
{{/maxLength}}
{{#minLength}}
// {{{name}}} ({{{dataType}}}) minLength
if(this.{{{name}}} != null && this.{{{name}}}.Length < {{minLength}})
{
yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, length must be greater than {{minLength}}.", new [] { "{{{name}}}" });
}
{{/minLength}}
{{#maximum}}
// {{{name}}} ({{{dataType}}}) maximum
if(this.{{{name}}} > ({{{dataType}}}){{maximum}})
{
yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must be a value less than or equal to {{maximum}}.", new [] { "{{{name}}}" });
}
{{/maximum}}
{{#minimum}}
// {{{name}}} ({{{dataType}}}) minimum
if(this.{{{name}}} < ({{{dataType}}}){{minimum}})
{
yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must be a value greater than or equal to {{minimum}}.", new [] { "{{{name}}}" });
}
{{/minimum}}
{{#pattern}}
{{^isByteArray}}
// {{{name}}} ({{{dataType}}}) pattern
Regex regex{{{name}}} = new Regex(@"{{{vendorExtensions.x-regex}}}"{{#vendorExtensions.x-modifiers}}{{#-first}}, {{/-first}}RegexOptions.{{{.}}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}});
if (false == regex{{{name}}}.Match(this.{{{name}}}).Success)
{
yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must match a pattern of " + regex{{{name}}}, new [] { "{{{name}}}" });
}
{{/isByteArray}}
{{/pattern}}
{{/hasValidation}}
{{/vars}}
yield break;
}
{{/validatable}}
{{/netStandard}}
}

View File

@ -0,0 +1,26 @@
{{^isContainer}}
/// <summary>
/// {{^description}}Defines {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
/// </summary>
{{#description}}
/// <value>{{description}}</value>
{{/description}}
{{#isString}}
[JsonConverter(typeof(StringEnumConverter))]
{{/isString}}
{{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}{{#vendorExtensions.x-enum-byte}}: byte{{/vendorExtensions.x-enum-byte}}
{
{{#allowableValues}}
{{#enumVars}}
/// <summary>
/// Enum {{name}} for value: {{{value}}}
/// </summary>
{{#isString}}
[EnumMember(Value = "{{{value}}}")]
{{/isString}}
{{name}}{{^isString}} = {{{value}}}{{/isString}}{{#isString}} = {{-index}}{{/isString}}{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
}
{{/isContainer}}

View File

@ -0,0 +1,19 @@
{{#models}}
{{#model}}
# {{{packageName}}}.{{modelPackage}}.{{{classname}}}
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
{{#parent}}
{{#parentVars}}
**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#readOnly}}[readonly] {{/readOnly}}{{#defaultValue}}[default to {{{.}}}]{{/defaultValue}}
{{/parentVars}}
{{/parent}}
{{#vars}}**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#readOnly}}[readonly] {{/readOnly}}{{#defaultValue}}[default to {{{.}}}]{{/defaultValue}}
{{/vars}}
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
{{/model}}
{{/models}}

View File

@ -0,0 +1,90 @@
{{>partial_header}}
using NUnit.Framework;
using System;
using System.Linq;
using System.IO;
using System.Collections.Generic;
using {{packageName}}.{{apiPackage}};
using {{packageName}}.{{modelPackage}};
using {{packageName}}.Client;
using System.Reflection;
using Newtonsoft.Json;
{{#models}}
{{#model}}
namespace {{packageName}}.Test
{
/// <summary>
/// Class for testing {{classname}}
/// </summary>
/// <remarks>
/// This file is automatically generated by OpenAPI Generator (https://openapi-generator.tech).
/// Please update the test case below to test the model.
/// </remarks>
[TestFixture]
public class {{classname}}Tests
{
// TODO uncomment below to declare an instance variable for {{classname}}
//private {{classname}} instance;
/// <summary>
/// Setup before each test
/// </summary>
[SetUp]
public void Init()
{
// TODO uncomment below to create an instance of {{classname}}
//instance = new {{classname}}();
}
/// <summary>
/// Clean up after each test
/// </summary>
[TearDown]
public void Cleanup()
{
}
/// <summary>
/// Test an instance of {{classname}}
/// </summary>
[Test]
public void {{classname}}InstanceTest()
{
// TODO uncomment below to test "IsInstanceOfType" {{classname}}
//Assert.IsInstanceOfType<{{classname}}> (instance, "variable 'instance' is a {{classname}}");
}
{{#discriminator}}
{{#children}}
/// <summary>
/// Test deserialize a {{classname}} from type {{parent}}
/// </summary>
[Test]
public void {{classname}}DeserializeFrom{{parent}}Test()
{
// TODO uncomment below to test deserialize a {{classname}} from type {{parent}}
//Assert.IsInstanceOf<{{parent}}>(JsonConvert.DeserializeObject<{{parent}}>(new {{classname}}().ToJson()));
}
{{/children}}
{{/discriminator}}
{{#vars}}
/// <summary>
/// Test the property '{{name}}'
/// </summary>
[Test]
public void {{name}}Test()
{
// TODO unit test for the property '{{name}}'
}
{{/vars}}
}
}
{{/model}}
{{/models}}

View File

@ -0,0 +1,22 @@
#!/usr/bin/env bash
#
# Generated by: https://github.com/openapitools/openapi-generator.git
#
wget -nc https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
mozroots --import --sync
echo "[INFO] remove bin/Debug/{{{packageName}}}.Test.dll"
rm src/{{{packageName}}}.Test/bin/Debug/{{{packageName}}}.Test.dll 2> /dev/null
echo "[INFO] install NUnit runners via NuGet"
wget -nc https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
mozroots --import --sync
mono nuget.exe install src/{{{packageName}}}.Test/packages.config -o packages
echo "[INFO] Install NUnit runners via NuGet"
mono nuget.exe install NUnit.Runners -Version 2.6.4 -OutputDirectory packages
echo "[INFO] Build the solution and run the unit test"
xbuild {{{packageName}}}.sln && \
mono ./packages/NUnit.Runners.2.6.4/tools/nunit-console.exe src/{{{packageName}}}.Test/bin/Debug/{{{packageName}}}.Test.dll

View File

@ -0,0 +1,46 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>{{targetFrameworkNuget}}</TargetFramework>
<AssemblyName>{{packageName}}</AssemblyName>
<PackageId>{{packageName}}</PackageId>
<OutputType>Library</OutputType>
<Authors>{{packageAuthors}}</Authors>
<Company>{{packageCompany}}</Company>
<AssemblyTitle>{{packageTitle}}</AssemblyTitle>
<Description>{{packageDescription}}</Description>
<Copyright>{{packageCopyright}}</Copyright>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<RootNamespace>{{packageName}}</RootNamespace>
<Version>{{packageVersion}}</Version>
</PropertyGroup>
<ItemGroup>
{{#netStandard}}
<PackageReference Include="FubarCoder.RestSharp.Portable.Core" Version="4.0.7" />
<PackageReference Include="FubarCoder.RestSharp.Portable.HttpClient" Version="4.0.7" />
{{/netStandard}}
{{^netStandard}}
<PackageReference Include="RestSharp" Version="105.1.0" />
{{/netStandard}}
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="JsonSubTypes" Version="1.2.0" />
</ItemGroup>
{{^netStandard}}
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
</ItemGroup>
{{/netStandard}}
</Project>

View File

@ -0,0 +1,49 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>{{targetFrameworkNuget}}</TargetFramework>
<AssemblyName>{{testPackageName}}</AssemblyName>
<PackageId>{{testPackageName}}</PackageId>
<OutputType>Library</OutputType>
<Authors>{{packageAuthors}}</Authors>
<Company>{{packageCompany}}</Company>
<AssemblyTitle>{{packageTitle}}</AssemblyTitle>
<Description>{{packageDescription}}</Description>
<Copyright>{{packageCopyright}}</Copyright>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<RootNamespace>{{testPackageName}}</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="2.6.4" />
{{#netStandard}}
<PackageReference Include="FubarCoder.RestSharp.Portable.Core" Version="4.0.7" />
{{/netStandard}}
{{^netStandard}}
<PackageReference Include="RestSharp" Version="105.1.0" />
{{/netStandard}}
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="JsonSubTypes" Version="1.2.0" />
</ItemGroup>
{{^netStandard}}
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
</ItemGroup>
{{/netStandard}}
<ItemGroup>
<ProjectReference Include="..\{{packageName}}\{{packageName}}.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,53 @@
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<!-- The identifier that must be unique within the hosting gallery -->
<id>$id$</id>
<title>{{packageTitle}}</title>
<!-- The package version number that is used when resolving dependencies -->
<version>$version$</version>
<!-- Authors contain text that appears directly on the gallery -->
<authors>$author$</authors>
<!-- Owners are typically nuget.org identities that allow gallery
users to earily find other packages by the same owners. -->
<owners>$author$</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<developmentDependency>false</developmentDependency>
<!-- The description can be used in package manager UI. Note that the
nuget.org gallery uses information you add in the portal. -->
<description>{{packageDescription}}</description>
{{#termsOfService}}
<copyright>{{termsOfService}}</copyright>
{{/termsOfService}}
{{#licenseUrl}}
<licenseUrl>{{licenseUrl}}</licenseUrl>
{{/licenseUrl}}
<!-- Dependencies are automatically installed when the package is installed -->
<dependencies>
<dependency id="NewtonSoft.Json" version="10.0.3" />
<dependency id="JsonSubTypes" version="1.2.0" />
<dependency id="RestSharp" version="105.1.0" />
{{#generatePropertyChanged}}
<dependency id="Fody" version="1.29.4" />
<dependency id="PropertyChanged.Fody" version="1.51.3" />
{{/generatePropertyChanged}}
</dependencies>
</metadata>
<files>
<!-- A readme.txt will be displayed when the package is installed -->
<file src="..\..\README.md" target="" />
<file src="..\..\docs\**\*.*" target="docs" />
{{#generatePropertyChanged}}
<file src="..\..\packages\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets" target="build" />
{{/generatePropertyChanged}}
</files>
</package>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="RestSharp" version="105.1.0" targetFramework="{{#isNet40}}net4{{/isNet40}}{{^isNet40}}{{targetFrameworkNuget}}{{/isNet40}}" developmentDependency="true" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="{{targetFrameworkNuget}}" developmentDependency="true" />
<package id="JsonSubTypes" version="1.2.0" targetFramework="{{targetFrameworkNuget}}" developmentDependency="true" />
{{#generatePropertyChanged}}
<package id="Fody" version="1.29.4" targetFramework="{{targetFrameworkNuget}}" developmentDependency="true" />
<package id="PropertyChanged.Fody" version="1.51.3" targetFramework="{{targetFrameworkNuget}}" developmentDependency="true" />
{{/generatePropertyChanged}}
</packages>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit" version="2.6.4" targetFramework="{{targetFrameworkNuget}}" />
<package id="RestSharp" version="105.1.0" targetFramework="{{#isNet40}}net4{{/isNet40}}{{^isNet40}}{{targetFrameworkNuget}}{{/isNet40}}" developmentDependency="true" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="{{targetFrameworkNuget}}" developmentDependency="true" />
<package id="JsonSubTypes" version="1.2.0" targetFramework="{{targetFrameworkNuget}}" developmentDependency="true" />
</packages>

View File

@ -0,0 +1,13 @@
/*
{{#appName}}
* {{{appName}}}
*
{{/appName}}
{{#appDescription}}
* {{{appDescription}}}
*
{{/appDescription}}
* {{#version}}OpenAPI spec version: {{{version}}}{{/version}}
* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
* Generated by: https://github.com/openapitools/openapi-generator.git
*/

View File

@ -0,0 +1,12 @@
{
"supports": {},
"dependencies": {
"FubarCoder.RestSharp.Portable.Core": "4.0.7",
"FubarCoder.RestSharp.Portable.HttpClient": "4.0.7",
"Newtonsoft.Json": "10.0.3",
"JsonSubTypes": "1.2.0"
},
"frameworks": {
"{{targetFrameworkNuget}}": {}
}
}

View File

@ -0,0 +1,9 @@
#
# Generated by: https://github.com/openapitools/openapi-generator.git
#
language: csharp
mono:
- latest
solution: {{{packageName}}}.sln
script:
- /bin/sh ./mono_nunit_test.sh

View File

@ -0,0 +1 @@
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}}

View File

@ -1,19 +1,27 @@
{{#hasEnums}}
import com.squareup.moshi.Json
{{/hasEnums}}
{{#parcelizeModels}}
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
{{/parcelizeModels}}
/**
* {{{description}}}
{{#vars}}
* @param {{name}} {{{description}}}
{{/vars}}
*/
{{#parcelizeModels}}
@Parcelize
{{/parcelizeModels}}
data class {{classname}} (
{{#requiredVars}}
{{>data_class_req_var}}{{^-last}},
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}},
{{/-last}}{{/optionalVars}}
) {
){{#parcelizeModels}} : Parcelable{{/parcelizeModels}} {
{{#hasEnums}}{{#vars}}{{#isEnum}}
/**
* {{{description}}}

View File

@ -1,16 +1,24 @@
{{#parcelizeModels}}
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
{{/parcelizeModels}}
/**
* {{{description}}}
{{#vars}}
* @param {{name}} {{{description}}}
{{/vars}}
*/
{{#parcelizeModels}}
@Parcelize
{{/parcelizeModels}}
data class {{classname}} (
{{#requiredVars}}
{{>data_class_req_var}}{{^-last}},
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}},
{{/-last}}{{/optionalVars}}
) {
){{#parcelizeModels}} : Parcelable{{/parcelizeModels}} {
{{#hasEnums}}{{#vars}}{{#isEnum}}
/**
* {{{description}}}

View File

@ -137,7 +137,7 @@ module {{moduleName}}
# Deserialize the response to the given return type.
#
# @param [Response] response HTTP response
# @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]"
# @param [String] return_type some examples: "User", "Array<User>", "Hash<String, Integer>"
def deserialize(response, return_type)
body = response.body

View File

@ -380,3 +380,17 @@ impl<T, C> Clone for Service<T, C>
}
}
}
/// Request parser for `Api`.
pub struct ApiRequestParser;
impl RequestParser for ApiRequestParser {
fn parse_operation_id(request: &Request) -> Result<&'static str, ()> {
let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path());
match request.method() {
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
// {{{operationId}}} - {{{httpMethod}}} {{{path}}}
&hyper::Method::{{{vendorExtensions.HttpMethod}}} if path.matched(paths::ID_{{{vendorExtensions.PATH_ID}}}) => Ok("{{{operationId}}}"),
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} _ => Err(()),
}
}
}

View File

@ -7,10 +7,10 @@
import Foundation
open class {{projectName}}API {
open static var basePath = "{{{basePath}}}"
open static var credential: URLCredential?
open static var customHeaders: [String:String] = [:]
open static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory()
public static var basePath = "{{{basePath}}}"
public static var credential: URLCredential?
public static var customHeaders: [String:String] = [:]
public static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory()
}
open class RequestBuilder<T> {

View File

@ -154,7 +154,7 @@ open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
if stringResponse.result.isFailure {
completion(
nil,
ErrorResponse.error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error as Error!)
ErrorResponse.error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error!)
)
return
}
@ -356,7 +356,7 @@ open class AlamofireDecodableRequestBuilder<T:Decodable>: AlamofireRequestBuilde
if stringResponse.result.isFailure {
completion(
nil,
ErrorResponse.error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error as Error!)
ErrorResponse.error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error!)
)
return
}

View File

@ -11,7 +11,7 @@ public typealias EncodeResult = (data: Data?, error: Error?)
open class CodableHelper {
open static var dateformatter: DateFormatter?
public static var dateformatter: DateFormatter?
open class func decode<T>(_ type: T.Type, from data: Data) -> (decodableObj: T?, error: Error?) where T : Decodable {
var returnedDecodable: T? = nil
@ -26,7 +26,7 @@ open class CodableHelper {
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
formatter.dateFormat = Configuration.dateFormat
decoder.dateDecodingStrategy = .formatted(formatter)
}
@ -55,7 +55,7 @@ open class CodableHelper {
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
formatter.dateFormat = Configuration.dateFormat
encoder.dateEncodingStrategy = .formatted(formatter)
}

Some files were not shown because too many files have changed in this diff Show More