forked from loafle/openapi-generator-original
Merge remote-tracking branch 'origin/3.4.x' into 4.0.x
This commit is contained in:
commit
2bcf5b2263
@ -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
|
||||
|
20
README.md
20
README.md
@ -2,16 +2,11 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`3.3.2`): [](https://travis-ci.org/OpenAPITools/openapi-generator)
|
||||
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`3.3.3`): [](https://travis-ci.org/OpenAPITools/openapi-generator)
|
||||
[](https://circleci.com/gh/OpenAPITools/openapi-generator)
|
||||
[](https://app.shippable.com/github/OpenAPITools/openapi-generator)
|
||||
[](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
|
||||
|
||||
[`3.4.x`](https://github.com/OpenAPITools/openapi-generator/tree/3.4.x) branch: [](https://travis-ci.org/OpenAPITools/openapi-generator)
|
||||
[](https://circleci.com/gh/OpenAPITools/openapi-generator)
|
||||
[](https://app.shippable.com/github/OpenAPITools/openapi-generator)
|
||||
[](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
|
||||
|
||||
[`4.0.x`](https://github.com/OpenAPITools/openapi-generator/tree/4.0.x) branch: [](https://travis-ci.org/OpenAPITools/openapi-generator)
|
||||
[](https://circleci.com/gh/OpenAPITools/openapi-generator)
|
||||
[](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.
|
||||
|
17
bin/csharp-refactor-petstore-all.sh
Executable file
17
bin/csharp-refactor-petstore-all.sh
Executable 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
37
bin/csharp-refactor-petstore.sh
Executable 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/
|
||||
|
28
bin/utils/test-fake-petstore-for-all.sh
Executable file
28
bin/utils/test-fake-petstore-for-all.sh
Executable 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
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
CMD ["help"]
|
||||
COPY docker-entrypoint.sh /usr/local/bin/
|
||||
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
|
||||
CMD ["help"]
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
```
|
||||
|
@ -1 +1 @@
|
||||
openApiGeneratorVersion=3.3.2
|
||||
openApiGeneratorVersion=3.3.3
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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";
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
@ -226,8 +229,8 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
|
||||
nameInCamelCase = sanitizeName(nameInCamelCase);
|
||||
}
|
||||
if (isReservedWord(nameInCamelCase) || nameInCamelCase.matches("^\\d.*")) {
|
||||
nameInCamelCase = escapeReservedWord(nameInCamelCase);
|
||||
}
|
||||
nameInCamelCase = escapeReservedWord(nameInCamelCase);
|
||||
}
|
||||
property.nameInCamelCase = nameInCamelCase;
|
||||
return property;
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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).");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
@ -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)) {
|
||||
|
@ -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)) {
|
||||
|
@ -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");
|
||||
|
@ -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)) {
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -0,0 +1 @@
|
||||
{{#allowableValues}}allowableValues="{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}{{^values}}range=[{{#min}}{{.}}{{/min}}{{^min}}-infinity{{/min}}, {{#max}}{{.}}{{/max}}{{^max}}infinity{{/max}}]{{/values}}"{{/allowableValues}}
|
@ -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
|
||||
|
@ -5,7 +5,9 @@ import {{invokerPackage}}.ApiException;
|
||||
import {{invokerPackage}}.ApiInvoker;
|
||||
import {{invokerPackage}}.Pair;
|
||||
|
||||
{{#hasModel}}
|
||||
import {{modelPackage}}.*;
|
||||
{{/hasModel}}
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -5,7 +5,9 @@ import {{invokerPackage}}.ApiInvoker;
|
||||
import {{invokerPackage}}.ApiException;
|
||||
import {{invokerPackage}}.Pair;
|
||||
|
||||
{{#hasModel}}
|
||||
import {{modelPackage}}.*;
|
||||
{{/hasModel}}
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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}}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Ref: https://github.com/Fody/Fody -->
|
||||
<Weavers>
|
||||
<PropertyChanged/>
|
||||
</Weavers>
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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}}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
214
modules/openapi-generator/src/main/resources/csharp-refactor/Multimap.mustache
Executable file
214
modules/openapi-generator/src/main/resources/csharp-refactor/Multimap.mustache
Executable 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
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -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}}
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
@ -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>
|
||||
|
@ -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}}
|
||||
}
|
@ -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}}
|
@ -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}}
|
||||
}
|
||||
|
||||
}
|
@ -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
|
@ -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
|
||||
|
@ -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}}
|
||||
}
|
@ -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'
|
||||
|
@ -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
|
@ -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}}
|
||||
}
|
@ -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}}
|
@ -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}}
|
||||
}
|
@ -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}}
|
@ -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}}
|
@ -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}}
|
@ -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
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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
|
||||
*/
|
@ -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}}": {}
|
||||
}
|
||||
}
|
@ -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
|
@ -0,0 +1 @@
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}}
|
@ -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}}}
|
||||
|
@ -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}}}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user