Compare commits

..

24 Commits

Author SHA1 Message Date
William Cheng
7fbf262206 test run in docker script 2020-06-05 00:05:00 +08:00
Alexey Volkov
6f6c8ede79 [Python] Fixed docstrings in api.mustache (#6391)
* [Python] Fixed docstrings

Fixes https://github.com/swagger-api/swagger-codegen/issues/9630

* Updated generated files

* Fixed python-experimental

* Updated generated files

* Fully fixed the format of the docstrings

* Updated generated files

* Updated generated files in openapi3
2020-06-04 08:46:35 -07:00
Jiri Kuncar
e708cdc83e [BUG][python] Support named arrays (#6493)
* [python] Support named arrays

* Fix named array type

* Use ModelSimple

* Reset samples

* Regenerated

* Animal farm test

* Array of enums

* Clean-up

* Clean-up

* Clean-up

* Fix array type generation

* simplify

* array model is not alias

* Array model has one value field

* ensure up-to-date

* ./bin/utils/ensure-up-to-date --batch

* Solve issue with missing import for array model

* regenerate
2020-06-04 07:50:53 -07:00
William Cheng
2be0afffe2 [Go] whitelist AdditionalProperties in the field name (#6543)
* whitelist AdditionalProperties in Go field name

* code format
2020-06-04 21:55:10 +08:00
Bruno Coelho
ae790ea74e [kotlin][client] remove tabs usage (#6526)
* [kotlin] remove tabs

* [kotlin][client] update pet projects
2020-06-04 21:29:08 +08:00
William Cheng
176c439a6d [PS] automatically derive discriminator mapping for oneOf/anyOf (#6542)
* infer mapping based on oneOf/anyOf schemas

* update files
2020-06-04 21:13:42 +08:00
Samuel Kahn
0f627e70fb [C++][Ue4] various bus fixes (#6539)
* Fixed compilation on linux and UE4.23

* Added string and enum type definition support

* Better handling or variable names, should avoid conflicts with reserved keywords or empty variable names in edge cases

* Updated samples
2020-06-04 20:37:39 +08:00
Reijhanniel Jearl Campos
83a0f7d65b Fix incorrect npx command (#6537)
The current `npx ` command says to use:

```
npx openapi-generator generate -i petstore.yaml -g ruby -o /tmp/test/
```

This however, pulls a similarly-named but different project: [zhang740/openapi-generator](https://www.npmjs.com/package/openapi-generator).

This commit fixes this, by using the appropriate package `@openapitools/openapi-generator-cli`
2020-06-04 20:24:51 +08:00
William Cheng
859e7f7228 update pester to 5.x (#6536) 2020-06-04 15:05:08 +08:00
William Cheng
b2c615b253 Merge branch 'master' of https://github.com/openapitools/openapi-generator 2020-06-04 11:50:34 +08:00
William Cheng
a25359e91c comment out openapi3 java jersey2-java8 tests 2020-06-04 11:46:16 +08:00
William Cheng
5cf4ee1de8 add additional properties support to powershell client generator (#6528) 2020-06-04 11:37:56 +08:00
William Cheng
a6bf956df5 [Go][Experimental] Support additionalProperties (#6525)
* support additonal properties in go

* support additonal properties marshal in go exp

* update go samples
2020-06-04 11:33:21 +08:00
sylvainmoindron
b2305d731c #5476 [kotlin] [spring] fix swagger and spring annotation for defaultValue (#6101) 2020-06-03 22:36:21 -04:00
Jim Schubert
244683d46a [samples] regenerate (#6533) 2020-06-03 21:28:25 -04:00
Jiri Kuncar
d07f459ce3 [python] Fix date-time parsing (#6458) 2020-06-03 21:26:30 -04:00
Dennis Melzer
e2e3405689 Register OAuth2ClientContext as bean (#6172)
* Register OAuth2ClientContext as bean

#6171

* Add tab

#6171

* Modify tests

#6171

* Add import for test

#6171

* Modify spring cloud async test

#6171
2020-06-03 15:36:19 +08:00
William Cheng
4d68953ded [Go][Experimental] Fix discriminator lookup (#6521)
* bug fix, better code format

* update oas3 sample
2020-06-03 01:11:41 +08:00
Justin Van Dort
8fc7ec8458 Typescript-rxjs: print param name (#6368)
* Prints out the parameter name in throwIfNullOrUndefined

* Fixed misspelling

Co-authored-by: Justin Van Dort <justinvandort@gmail.com>
Co-authored-by: Esteban Gehring <esteban.gehring@bithost.ch>
2020-06-02 12:46:30 +02:00
William Cheng
66a3ec7cf0 add oneof discrimistrator lookup to go experimental (#6517) 2020-06-02 16:50:35 +08:00
William Cheng
c1cf63e81c [PowerShell] Add useOneOfDiscriminatorLookup option (#6516)
* add useOneOfDiscriminatorLookup option

* update doc
2020-06-02 14:07:05 +08:00
William Cheng
0fbbbe8a95 add discriminator support to anyOf powershell client (#6512) 2020-06-02 10:55:56 +08:00
William Cheng
4c3eb0d973 [Go][Experimental] Add discriminator support to anyOf (#6511)
* add discriminator support in anyof

* update samples
2020-06-02 10:54:57 +08:00
Jim Schubert
58ed6afc0d Update Generate.java (#6515)
Removed missed -D messages
2020-06-01 21:08:50 -04:00
988 changed files with 7870 additions and 48817 deletions

View File

@@ -21,9 +21,6 @@ cache:
- $HOME/samples/client/petstore/php/OpenAPIToolsClient-php/vendor
- $HOME/samples/client/petstore/ruby/vendor/bundle
- $HOME/samples/client/petstore/python/.venv/
- $HOME/samples/openapi3/client/petstore/typescript/tests/default/node_modules
- $HOME/samples/openapi3/client/petstore/typescript/tests/jquery/node_modules
- $HOME/samples/openapi3/client/petstore/typescript/tests/object_params/node_modules
- $HOME/samples/client/petstore/typescript-node/npm/node_modules
- $HOME/samples/client/petstore/typescript-node/npm/typings/
- $HOME/samples/client/petstore/typescript-fetch/tests/default/node_modules
@@ -133,6 +130,7 @@ install:
script:
# fail fast
- set -e
- ./run-in-docker.sh mvn clean package
# fail if templates/generators contain carriage return '\r'
- /bin/bash ./bin/utils/detect_carriage_return.sh
# fail if generators contain merge conflicts

View File

@@ -32,7 +32,7 @@ install:
- git clone https://github.com/wing328/swagger-samples
- ps: Start-Process -FilePath 'C:\maven\apache-maven-3.2.5\bin\mvn' -ArgumentList 'jetty:run' -WorkingDirectory "$env:appveyor_build_folder\swagger-samples\java\java-jersey-jaxrs-ci"
- ps: $PSVersionTable.PSVersion
- ps: Install-Module Pester -Force -Scope CurrentUser -RequiredVersion 4.3.1
- ps: Install-Module Pester -Force -Scope CurrentUser
build_script:
- dotnet --info
# build C# API client (netcore)

View File

@@ -1,42 +0,0 @@
#!/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"
echo "Creating default (fetch) client!"
ags="generate -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g typescript -o samples/openapi3/client/petstore/typescript/builds/default --additional-properties=platform=node,npmName=ts-petstore-client $@"
java $JAVA_OPTS -jar $executable $ags
echo "Creating jquery client!"
ags="generate -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g typescript -o samples/openapi3/client/petstore/typescript/builds/jquery --additional-properties=framework=jquery,npmName=ts-petstore-client $@"
java $JAVA_OPTS -jar $executable $ags
echo "Creating fetch object client!"
ags="generate -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g typescript -o samples/openapi3/client/petstore/typescript/builds/object_params --additional-properties=platform=node,npmName=ts-petstore-client,useObjectParameters $@"
java $JAVA_OPTS -jar $executable $ags

View File

@@ -49,7 +49,6 @@ declare -a samples=(
#"${root}/bin/php-slim4-server-petstore.sh"
"${root}/bin/php-ze-ph-petstore-server.sh"
"${root}/bin/openapi3/php-petstore.sh"
"${root}/bin/typescript.sh"
"${root}/bin/typescript-angularjs-petstore.sh"
"${root}/bin/typescript-angular-petstore-all.sh"
"${root}/bin/typescript-aurelia-petstore.sh"

View File

@@ -1,16 +0,0 @@
set executable=.\modules\openapi-generator-cli\target\openapi-generator-cli.jar
If Not Exist %executable% (
mvn clean package
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\openapi-generator\src\test\resources\3_0\petstore.yaml -g typescript -o samples\openapi3\client\petstore\typescript\builds\default --additional-properties=platform=node,npmName=ts-petstore-client
java %JAVA_OPTS% -jar %executable% %ags%
ags=generate -i modules\openapi-generator\src\test\resources\3_0\petstore.yaml -g typescript -o samples\openapi3\client\petstore\typescript\builds\jquery --additional-properties=framework=jquery,npmName=ts-petstore-client
java %JAVA_OPTS% -jar %executable% %ags%
set ags=generate -i modules\openapi-generator\src\test\resources\3_0\petstore.yaml -g typescript -o samples\openapi3\client\petstore\typescript\builds\object_params --additional-properties=platform=node,npmName=ts-petstore-client,useObjectParameters
java %JAVA_OPTS% -jar %executable% %ags%

View File

@@ -60,7 +60,6 @@ The following generators are available:
* [scalaz](generators/scalaz.md)
* [swift4-deprecated (deprecated)](generators/swift4-deprecated.md)
* [swift5 (beta)](generators/swift5.md)
* [typescript (experimental)](generators/typescript.md)
* [typescript-angular](generators/typescript-angular.md)
* [typescript-angularjs](generators/typescript-angularjs.md)
* [typescript-aurelia](generators/typescript-aurelia.md)

View File

@@ -12,6 +12,7 @@ sidebar_label: go-experimental
|packageVersion|Go package version.| |1.0.0|
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|structPrefix|whether to prefix struct with the class name. e.g. DeletePetOpts =&gt; PetApiDeletePetOpts| |false|
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and onlye one match in oneOf's schemas) will be skipped.| |false|
|withAWSV4Signature|whether to include AWS v4 signature support| |false|
|withGoCodegenComment|whether to include Go codegen comment to disable Go Lint and collapse by default in GitHub PRs and diffs| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

View File

@@ -11,6 +11,7 @@ sidebar_label: powershell
|packageName|Client package name (e.g. PSTwitter).| |PSOpenAPITools|
|packageVersion|Package version (e.g. 0.1.2).| |0.1.2|
|powershellGalleryUrl|URL to the module in PowerShell Gallery (e.g. https://www.powershellgallery.com/packages/PSTwitter/).| |null|
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and onlye one match in oneOf's schemas) will be skipped.| |null|
## IMPORT MAPPING

View File

@@ -1,241 +0,0 @@
---
title: Config Options for typescript
sidebar_label: typescript
---
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|disallowAdditionalPropertiesIfNotPresent|Specify the behavior when the 'additionalProperties' keyword is not present in the OAS document
If false: the 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications. If true: when the 'additionalProperties' keyword is not present in a schema, the value of 'additionalProperties' is set to false, i.e. no additional properties are allowed. Note: this mode is not compliant with the JSON schema specification. This is the original openapi-generator behavior.This setting is currently ignored for OAS 2.0 documents: 1) When the 'additionalProperties' keyword is not present in a 2.0 schema, additional properties are NOT allowed. 2) Boolean values of the 'additionalProperties' keyword are ignored. It's as if additional properties are NOT allowed.Note: the root cause are issues #1369 and #1371, which must be resolved in the swagger-parser project.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>when the 'additionalProperties' keyword is not present in a schema, the value of 'additionalProperties' is automatically set to false, i.e. no additional properties are allowed. Note: this mode is not compliant with the JSON schema specification. This is the original openapi-generator behavior.</dd></dl>|true|
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|fileContentDataType|Specifies the type to use for the content of a file - i.e. Blob (Browser) / Buffer (node)| |Buffer|
|framework|Specify the framework which should be used in the client code.|<dl><dt>**fetch-api**</dt><dd>fetch-api</dd><dt>**jquery**</dt><dd>jquery</dd></dl>|fetch-api|
|legacyDiscriminatorBehavior|This flag is used by OpenAPITools codegen to influence the processing of the discriminator attribute in OpenAPI documents. This flag has no impact if the OAS document does not use the discriminator attribute. The default value of this flag is set in each language-specific code generator (e.g. Python, Java, go...)using the method toModelName. Note to developers supporting a language generator in OpenAPITools; to fully support the discriminator attribute as defined in the OAS specification 3.x, language generators should set this flag to true by default; however this requires updating the mustache templates to generate a language-specific discriminator lookup function that iterates over {{#mappedModels}} and does not iterate over {{children}}, {{#anyOf}}, or {{#oneOf}}.|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
|modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase|
|npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null|
|npmRepository|Use this property to set an url your private npmRepo in the package.json| |null|
|npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0|
|platform|Specifies the platform the code should run on. The default is 'node' for the 'request' framework and 'browser' otherwise.|<dl><dt>**browser**</dt><dd>browser</dd><dt>**node**</dt><dd>node</dd></dl>|browser|
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|supportsES6|Generate code that conforms to ES6.| |false|
|useObjectParameters|useObjectParameters| |false|
|useRxJS|Enable this to internally use rxjs observables. If disabled, a stub is used instead. This is required for the 'angular' framework.| |false|
## IMPORT MAPPING
| Type/Alias | Imports |
| ---------- | ------- |
## INSTANTIATION TYPES
| Type/Alias | Instantiated By |
| ---------- | --------------- |
|array|Array|
## LANGUAGE PRIMITIVES
<ul class="column-ul">
<li>Array</li>
<li>Boolean</li>
<li>Date</li>
<li>Double</li>
<li>Error</li>
<li>File</li>
<li>Float</li>
<li>Integer</li>
<li>Long</li>
<li>Map</li>
<li>Object</li>
<li>String</li>
<li>any</li>
<li>boolean</li>
<li>number</li>
<li>string</li>
</ul>
## RESERVED WORDS
<ul class="column-ul">
<li>abstract</li>
<li>await</li>
<li>boolean</li>
<li>break</li>
<li>byte</li>
<li>case</li>
<li>catch</li>
<li>char</li>
<li>class</li>
<li>const</li>
<li>continue</li>
<li>debugger</li>
<li>default</li>
<li>delete</li>
<li>do</li>
<li>double</li>
<li>else</li>
<li>enum</li>
<li>export</li>
<li>extends</li>
<li>false</li>
<li>final</li>
<li>finally</li>
<li>float</li>
<li>for</li>
<li>formParams</li>
<li>function</li>
<li>goto</li>
<li>headerParams</li>
<li>if</li>
<li>implements</li>
<li>import</li>
<li>in</li>
<li>instanceof</li>
<li>int</li>
<li>interface</li>
<li>let</li>
<li>long</li>
<li>native</li>
<li>new</li>
<li>null</li>
<li>package</li>
<li>private</li>
<li>protected</li>
<li>public</li>
<li>queryParameters</li>
<li>requestOptions</li>
<li>return</li>
<li>short</li>
<li>static</li>
<li>super</li>
<li>switch</li>
<li>synchronized</li>
<li>this</li>
<li>throw</li>
<li>transient</li>
<li>true</li>
<li>try</li>
<li>typeof</li>
<li>useFormData</li>
<li>var</li>
<li>varLocalDeferred</li>
<li>varLocalPath</li>
<li>void</li>
<li>volatile</li>
<li>while</li>
<li>with</li>
<li>yield</li>
</ul>
## FEATURE SET
### Client Modification Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasePath|✗|ToolingExtension
|Authorizations|✗|ToolingExtension
|UserAgent|✗|ToolingExtension
### Data Type Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Custom|✗|OAS2,OAS3
|Int32|✓|OAS2,OAS3
|Int64|✓|OAS2,OAS3
|Float|✓|OAS2,OAS3
|Double|✓|OAS2,OAS3
|Decimal|✓|ToolingExtension
|String|✓|OAS2,OAS3
|Byte|✓|OAS2,OAS3
|Binary|✓|OAS2,OAS3
|Boolean|✓|OAS2,OAS3
|Date|✓|OAS2,OAS3
|DateTime|✓|OAS2,OAS3
|Password|✓|OAS2,OAS3
|File|✓|OAS2
|Array|✓|OAS2,OAS3
|Maps|✓|ToolingExtension
|CollectionFormat|✓|OAS2
|CollectionFormatMulti|✓|OAS2
|Enum|✓|OAS2,OAS3
|ArrayOfEnum|✓|ToolingExtension
|ArrayOfModel|✓|ToolingExtension
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|ArrayOfCollectionOfModel|✓|ToolingExtension
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|MapOfEnum|✓|ToolingExtension
|MapOfModel|✓|ToolingExtension
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|MapOfCollectionOfModel|✓|ToolingExtension
|MapOfCollectionOfEnum|✓|ToolingExtension
### Documentation Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Readme|✗|ToolingExtension
|Model|✓|ToolingExtension
|Api|✓|ToolingExtension
### Global Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Host|✓|OAS2,OAS3
|BasePath|✓|OAS2,OAS3
|Info|✓|OAS2,OAS3
|Schemes|✗|OAS2,OAS3
|PartialSchemes|✓|OAS2,OAS3
|Consumes|✓|OAS2
|Produces|✓|OAS2
|ExternalDocumentation|✓|OAS2,OAS3
|Examples|✓|OAS2,OAS3
|XMLStructureDefinitions|✗|OAS2,OAS3
|MultiServer|✗|OAS3
|ParameterizedServer|✗|OAS3
|ParameterStyling|✗|OAS3
|Callbacks|✓|OAS3
|LinkObjects|✗|OAS3
### Parameter Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Path|✓|OAS2,OAS3
|Query|✓|OAS2,OAS3
|Header|✓|OAS2,OAS3
|Body|✓|OAS2
|FormUnencoded|✓|OAS2
|FormMultipart|✓|OAS2
|Cookie|✓|OAS3
### Schema Support Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Simple|✓|OAS2,OAS3
|Composite|✓|OAS2,OAS3
|Polymorphism|✓|OAS2,OAS3
|Union|✗|OAS3
### Security Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasicAuth|✓|OAS2,OAS3
|ApiKey|✓|OAS2,OAS3
|OpenIDConnect|✗|OAS3
|BearerToken|✓|OAS3
|OAuth2_Implicit|✓|OAS2,OAS3
|OAuth2_Password|✓|OAS2,OAS3
|OAuth2_ClientCredentials|✓|OAS2,OAS3
|OAuth2_AuthorizationCode|✓|OAS2,OAS3
### Wire Format Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|JSON|✓|OAS2,OAS3
|XML|✓|OAS2,OAS3
|PROTOBUF|✗|ToolingExtension
|Custom|✗|OAS2,OAS3

View File

@@ -33,7 +33,7 @@ npm install @openapitools/openapi-generator-cli -D
Then, **generate** a ruby client from a valid [petstore.yaml](https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml) doc:
```bash
npx openapi-generator generate -i petstore.yaml -g ruby -o /tmp/test/
npx @openapitools/openapi-generator-cli generate -i petstore.yaml -g ruby -o /tmp/test/
```
> `npx` will execute a globally available `openapi-generator`, and if not found it will fall back to project-local commands. The result is that the above command will work regardless of which installation method you've chosen.

View File

@@ -230,7 +230,7 @@ public class Generate extends OpenApiGeneratorCommand {
@Option(name = {"--log-to-stderr"},
title = "Log to STDERR",
description = "write all log messages (not just errors) to STDOUT."
+ " Useful for piping the JSON output of debug options (e.g. `-DdebugOperations`) to an external parser directly while testing a generator.")
+ " Useful for piping the JSON output of debug options (e.g. `--global-property debugOperations`) to an external parser directly while testing a generator.")
private Boolean logToStderr;
@Option(name = {"--enable-post-process-file"}, title = "enable post-process file", description = CodegenConstants.ENABLE_POST_PROCESS_FILE_DESC)
@@ -407,7 +407,6 @@ public class Generate extends OpenApiGeneratorCommand {
}
if (globalProperties != null && !globalProperties.isEmpty()) {
System.err.println("[DEPRECATED] -D arguments after 'generate' are application arguments and not Java System Properties, please consider changing to --global-property, apply your system properties to JAVA_OPTS, or move the -D arguments before the jar option.");
applyGlobalPropertiesKvpList(globalProperties, configurator);
}
applyInstantiationTypesKvpList(instantiationTypes, configurator);

View File

@@ -375,4 +375,6 @@ public class CodegenConstants {
" 2) Boolean values of the 'additionalProperties' keyword are ignored. It's as if additional properties are NOT allowed." +
"Note: the root cause are issues #1369 and #1371, which must be resolved in the swagger-parser project.";
public static final String USE_ONEOF_DISCRIMINATOR_LOOKUP = "useOneOfDiscriminatorLookup";
public static final String USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC = "Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and onlye one match in oneOf's schemas) will be skipped.";
}

View File

@@ -30,8 +30,8 @@ public class CodegenOperation {
isResponseBinary = false, isResponseFile = false, hasReference = false,
isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
isRestful, isDeprecated, isCallbackRequest, uniqueItems;
public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
public String path, operationId, returnType, httpMethod, returnBaseType,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
public CodegenDiscriminator discriminator;
public List<Map<String, String>> consumes, produces, prioritizedContentTypes;
public List<CodegenServer> servers = new ArrayList<CodegenServer>();

View File

@@ -3499,9 +3499,8 @@ public class DefaultCodegen implements CodegenConfig {
op.examples = new ExampleGenerator(schemas, this.openAPI).generateFromResponseSchema(exampleStatusCode, responseSchema, getProducesInfo(this.openAPI, operation));
op.defaultResponse = toDefaultValue(responseSchema);
op.returnType = cm.dataType;
op.returnFormat = cm.dataFormat;
op.hasReference = schemas != null && schemas.containsKey(op.returnBaseType);
op.hasReference = schemas.containsKey(op.returnBaseType);
// lookup discriminator
Schema schema = schemas.get(op.returnBaseType);
if (schema != null) {
@@ -4313,7 +4312,7 @@ public class DefaultCodegen implements CodegenConfig {
return false;
}
}
// TODO revise below as it should be replaced by ModelUtils.isFileSchema(parameterSchema)
public boolean isDataTypeFile(String dataType) {
if (dataType != null) {

View File

@@ -29,7 +29,6 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore;
@@ -94,7 +93,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
"byte",
"map[string]interface{}",
"interface{}"
)
)
);
instantiationTypes.clear();
@@ -210,6 +209,11 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
if (name.matches("^\\d.*"))
name = "Var" + name;
if ("AdditionalProperties".equals(name)) {
// AdditionalProperties is a reserved field (additionalProperties: true), use AdditionalPropertiesField instead
return "AdditionalPropertiesField";
}
return name;
}
@@ -320,7 +324,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
/**
* Return the golang implementation type for the specified property.
*
*
* @param p the OAS property.
* @return the golang implementation type.
*/
@@ -378,7 +382,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
/**
* Return the OpenAPI type for the property.
*
*
* @param p the OAS property.
* @return the OpenAPI type.
*/
@@ -404,20 +408,19 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
/**
* Determines the golang instantiation type of the specified schema.
*
* <p>
* This function is called when the input schema is a map, and specifically
* when the 'additionalProperties' attribute is present in the OAS specification.
* Codegen invokes this function to resolve the "parent" association to
* 'additionalProperties'.
*
* <p>
* Note the 'parent' attribute in the codegen model is used in the following scenarios:
* - Indicate a polymorphic association with some other type (e.g. class inheritance).
* - If the specification has a discriminator, cogegen create a “parent” based on the discriminator.
* - Use of the 'additionalProperties' attribute in the OAS specification.
* This is the specific scenario when codegen invokes this function.
* This is the specific scenario when codegen invokes this function.
*
* @param property the input schema
*
* @return the golang instantiation type of the specified property.
*/
@Override

View File

@@ -497,13 +497,20 @@ public class CppUE4ClientCodegen extends AbstractCppCodegen {
name = name.toLowerCase(Locale.ROOT);
}
//Unreal variable names are CamelCase
String camelCaseName = camelize(name, false);
//Avoid empty variable name at all costs
if(!camelCaseName.isEmpty()) {
name = camelCaseName;
}
// for reserved word or word starting with number, append _
if (isReservedWord(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
//Unreal variable names are CamelCase
return camelize(name, false);
return name;
}
@Override

View File

@@ -35,6 +35,7 @@ public class GoClientExperimentalCodegen extends GoClientCodegen {
private static final Logger LOGGER = LoggerFactory.getLogger(GoClientExperimentalCodegen.class);
protected String goImportAlias = "openapiclient";
protected boolean useOneOfDiscriminatorLookup = false; // use oneOf discriminator's mapping for model lookup
public GoClientExperimentalCodegen() {
super();
@@ -44,6 +45,8 @@ public class GoClientExperimentalCodegen extends GoClientCodegen {
usesOptionals = false;
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata).stability(Stability.EXPERIMENTAL).build();
cliOptions.add(new CliOption(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC).defaultValue("false"));
}
/**
@@ -93,6 +96,20 @@ public class GoClientExperimentalCodegen extends GoClientCodegen {
additionalProperties.put("goImportAlias", goImportAlias);
}
if (additionalProperties.containsKey(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP)) {
setUseOneOfDiscriminatorLookup(convertPropertyToBooleanAndWriteBack(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP));
} else {
additionalProperties.put(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, useOneOfDiscriminatorLookup);
}
}
public void setUseOneOfDiscriminatorLookup(boolean useOneOfDiscriminatorLookup) {
this.useOneOfDiscriminatorLookup = useOneOfDiscriminatorLookup;
}
public boolean getUseOneOfDiscriminatorLookup() {
return this.useOneOfDiscriminatorLookup;
}
public void setGoImportAlias(String goImportAlias) {
@@ -205,9 +222,12 @@ public class GoClientExperimentalCodegen extends GoClientCodegen {
if (model.anyOf != null && !model.anyOf.isEmpty()) {
imports.add(createMapping("import", "fmt"));
}
// add x-additional-properties
if ("map[string]map[string]interface{}".equals(model.parent)) {
model.vendorExtensions.put("x-additional-properties", true);
}
}
}
return objs;
}

View File

@@ -53,6 +53,7 @@ public class PowerShellClientCodegen extends DefaultCodegen implements CodegenCo
protected HashSet powershellVerbs;
protected Map<String, String> commonVerbs; // verbs not in the official ps verb list but can be mapped to one of the verbs
protected HashSet methodNames; // store a list of method names to detect duplicates
protected boolean useOneOfDiscriminatorLookup = false; // use oneOf discriminator's mapping for model lookup
/**
* Constructs an instance of `PowerShellClientCodegen`.
@@ -498,7 +499,7 @@ public class PowerShellClientCodegen extends DefaultCodegen implements CodegenCo
cliOptions.add(new CliOption(CodegenConstants.OPTIONAL_PROJECT_GUID, "GUID for PowerShell module (e.g. a27b908d-2a20-467f-bc32-af6f3a654ac5). A random GUID will be generated by default."));
cliOptions.add(new CliOption(CodegenConstants.API_NAME_PREFIX, "Prefix that will be appended to all PS objects. Default: empty string. e.g. Pet => PSPet."));
cliOptions.add(new CliOption("commonVerbs", "PS common verb mappings. e.g. Delete=Remove:Patch=Update to map Delete with Remove and Patch with Update accordingly."));
cliOptions.add(new CliOption(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC));
}
public CodegenType getTag() {
@@ -535,6 +536,14 @@ public class PowerShellClientCodegen extends DefaultCodegen implements CodegenCo
this.powershellGalleryUrl = powershellGalleryUrl;
}
public void setUseOneOfDiscriminatorLookup(boolean useOneOfDiscriminatorLookup) {
this.useOneOfDiscriminatorLookup = useOneOfDiscriminatorLookup;
}
public boolean getUseOneOfDiscriminatorLookup() {
return this.useOneOfDiscriminatorLookup;
}
@Override
public void processOpts() {
super.processOpts();
@@ -550,6 +559,12 @@ public class PowerShellClientCodegen extends DefaultCodegen implements CodegenCo
additionalProperties.put("powershellGalleryUrl", powershellGalleryUrl);
}
if (additionalProperties.containsKey(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP)) {
setUseOneOfDiscriminatorLookup(convertPropertyToBooleanAndWriteBack(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP));
} else {
additionalProperties.put(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, useOneOfDiscriminatorLookup);
}
if (StringUtils.isNotBlank(powershellGalleryUrl)) {
// get the last segment of the URL
// e.g. https://www.powershellgallery.com/packages/PSTwitter => PSTwitter
@@ -907,6 +922,31 @@ public class PowerShellClientCodegen extends DefaultCodegen implements CodegenCo
model.anyOf.remove("ModelNull");
}
// add vendor extension for additonalProperties: true
if ("null<String, SystemCollectionsHashtable>".equals(model.parent)) {
model.vendorExtensions.put("x-additional-properties", true);
}
// automatically create discriminator mapping for oneOf/anyOf if not present
if (((model.oneOf != null && !model.oneOf.isEmpty()) || (model.anyOf != null && !model.anyOf.isEmpty())) &&
model.discriminator != null && model.discriminator.getMapping() == null) {
// create mappedModels
Set<String> schemas = new HashSet<>();
if (model.oneOf != null && !model.oneOf.isEmpty()) {
schemas = model.oneOf;
} else if (model.anyOf != null && !model.anyOf.isEmpty()) {
schemas = model.anyOf;
}
HashSet<CodegenDiscriminator.MappedModel> mappedModels = new HashSet<>();
for (String s: schemas) {
mappedModels.add(new CodegenDiscriminator.MappedModel(s, s));
}
model.discriminator.setMappedModels(mappedModels);
}
}
return objs;

View File

@@ -722,7 +722,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
}
// correct "&#39;"s into "'"s after toString()
if (ModelUtils.isStringSchema(schema) && schema.getDefault() != null) {
if (ModelUtils.isStringSchema(schema) && schema.getDefault() != null && !ModelUtils.isDateSchema(schema) && !ModelUtils.isDateTimeSchema(schema)) {
example = (String) schema.getDefault();
}

View File

@@ -38,8 +38,9 @@ import org.openapitools.codegen.meta.Stability;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.io.File;
import java.util.*;
import java.util.regex.Pattern;
@@ -196,15 +197,15 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
return "python-experimental";
}
public String dateToString(Schema p, Date date, DateFormat dateFormatter, DateFormat dateTimeFormatter) {
public String dateToString(Schema p, OffsetDateTime date, DateTimeFormatter dateFormatter, DateTimeFormatter dateTimeFormatter) {
// converts a date into a date or date-time python string
if (!(ModelUtils.isDateSchema(p) || ModelUtils.isDateTimeSchema(p))) {
throw new RuntimeException("passed schema must be of type Date or DateTime");
}
if (ModelUtils.isDateSchema(p)) {
return "dateutil_parser('" + dateFormatter.format(date) + "').date()";
return "dateutil_parser('" + date.format(dateFormatter) + "').date()";
}
return "dateutil_parser('" + dateTimeFormatter.format(date) + "')";
return "dateutil_parser('" + date.format(dateTimeFormatter) + "')";
}
/**
@@ -228,20 +229,17 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
}
// convert datetime and date enums if they exist
DateFormat iso8601Date = new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT);
DateFormat iso8601DateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ROOT);
TimeZone utc = TimeZone.getTimeZone("UTC");
iso8601Date.setTimeZone(utc);
iso8601DateTime.setTimeZone(utc);
DateTimeFormatter iso8601Date = DateTimeFormatter.ISO_DATE;
DateTimeFormatter iso8601DateTime = DateTimeFormatter.ISO_DATE_TIME;
if (ModelUtils.isDateSchema(p) || ModelUtils.isDateTimeSchema(p)) {
List<Object> currentEnum = p.getEnum();
List<String> fixedEnum = new ArrayList<String>();
String fixedValue = null;
Date date = null;
OffsetDateTime date = null;
if (currentEnum != null && !currentEnum.isEmpty()) {
for (Object enumItem : currentEnum) {
date = (Date) enumItem;
date = (OffsetDateTime) enumItem;
fixedValue = dateToString(p, date, iso8601Date, iso8601DateTime);
fixedEnum.add(fixedValue);
}
@@ -251,15 +249,21 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
// convert the example if it exists
Object currentExample = p.getExample();
if (currentExample != null) {
date = (Date) currentExample;
try {
date = (OffsetDateTime) currentExample;
} catch (ClassCastException e) {
date = ((Date) currentExample).toInstant().atOffset(ZoneOffset.UTC);
LOGGER.warn("Invalid `date-time` format for value {}", currentExample);
}
fixedValue = dateToString(p, date, iso8601Date, iso8601DateTime);
fixedEnum.add(fixedValue);
p.setExample(fixedValue);
LOGGER.warn(fixedValue);
}
// fix defaultObject
if (defaultObject != null) {
date = (Date) defaultObject;
date = (OffsetDateTime) defaultObject;
fixedValue = dateToString(p, date, iso8601Date, iso8601DateTime);
p.setDefault(fixedValue);
defaultObject = fixedValue;
@@ -377,7 +381,7 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
/**
* Override with special post-processing for all models.
*/
*/
@SuppressWarnings({"static-method", "unchecked"})
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
// loop through all models and delete ones where type!=object and the model has no validations and enums
@@ -417,14 +421,12 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
Schema modelSchema = ModelUtils.getSchema(this.openAPI, cm.name);
CodegenProperty modelProperty = fromProperty("value", modelSchema);
if (cm.isEnum || cm.isAlias) {
if (!modelProperty.isEnum && !modelProperty.hasValidation) {
if (!modelProperty.isEnum && !modelProperty.hasValidation && !cm.isArrayModel) {
// remove these models because they are aliases and do not have any enums or validations
modelSchemasToRemove.put(cm.name, modelSchema);
}
} else if (cm.isArrayModel && !modelProperty.isEnum && !modelProperty.hasValidation) {
// remove any ArrayModels which lack validation and enums
modelSchemasToRemove.put(cm.name, modelSchema);
}
}
}
@@ -825,10 +827,10 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
result.unescapedDescription = simpleModelName(name);
// make non-object type models have one property so we can use it to store enums and validations
if (result.isAlias || result.isEnum) {
if (result.isAlias || result.isEnum || result.isArrayModel) {
Schema modelSchema = ModelUtils.getSchema(this.openAPI, result.name);
CodegenProperty modelProperty = fromProperty("value", modelSchema);
if (modelProperty.isEnum == true || modelProperty.hasValidation == true) {
if (modelProperty.isEnum == true || modelProperty.hasValidation == true || result.isArrayModel) {
// these models are non-object models with enums and/or validations
// add a single property to the model so we can have a way to access validations
result.isAlias = true;
@@ -843,7 +845,6 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
postProcessModelProperty(result, prop);
}
}
}
}
@@ -905,7 +906,7 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
* Primitive types in the OAS specification are implemented in Python using the corresponding
* Python primitive types.
* Composed types (e.g. allAll, oneOf, anyOf) are represented in Python using list of types.
*
*
* The caller should set the prefix and suffix arguments to empty string, except when
* getTypeString invokes itself recursively. A non-empty prefix/suffix may be specified
* to wrap the return value in a python dict, list or tuple.
@@ -913,7 +914,7 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
* Examples:
* - "bool, date, float" The data must be a bool, date or float.
* - "[bool, date]" The data must be an array, and the array items must be a bool or date.
*
*
* @param p The OAS schema.
* @param prefix prepended to the returned value.
* @param suffix appended to the returned value.
@@ -922,7 +923,6 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
* @return a comma-separated string representation of the Python types
*/
private String getTypeString(Schema p, String prefix, String suffix, List<String> referencedModelNames) {
// this is used to set dataType, which defines a python tuple of classes
String fullSuffix = suffix;
if (")".equals(suffix)) {
fullSuffix = "," + suffix;
@@ -968,7 +968,7 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
} else {
return prefix + getTypeString(inner, "[", "]", referencedModelNames) + fullSuffix;
}
}
}
if (ModelUtils.isFileSchema(p)) {
return prefix + "file_type" + fullSuffix;
}

View File

@@ -1,843 +0,0 @@
/*
* Copyright 2020 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 io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.NumberSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore;
public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(TypeScriptClientCodegen.class);
private static final String X_DISCRIMINATOR_TYPE = "x-discriminator-value";
private static final String UNDEFINED_VALUE = "undefined";
private static final String FRAMEWORK_SWITCH = "framework";
private static final String FRAMEWORK_SWITCH_DESC = "Specify the framework which should be used in the client code.";
private static final String[] FRAMEWORKS = { "fetch-api", "jquery" };
private static final String PLATFORM_SWITCH = "platform";
private static final String PLATFORM_SWITCH_DESC = "Specifies the platform the code should run on. The default is 'node' for the 'request' framework and 'browser' otherwise.";
private static final String[] PLATFORMS = { "browser", "node" };
private static final String FILE_CONTENT_DATA_TYPE= "fileContentDataType";
private static final String FILE_CONTENT_DATA_TYPE_DESC = "Specifies the type to use for the content of a file - i.e. Blob (Browser) / Buffer (node)";
private static final String USE_RXJS_SWITCH = "useRxJS";
private static final String USE_RXJS_SWITCH_DESC = "Enable this to internally use rxjs observables. If disabled, a stub is used instead. This is required for the 'angular' framework.";
private static final String USE_OBJECT_PARAMS_SWITCH = "useObjectParameters";
private static final String USE_OBJECT_PARAMS_DESC = "Use aggregate parameter objects as function arguments for api operations instead of passing each parameter as a separate function argument.";
private final Map<String, String> frameworkToHttpLibMap;
// NPM Options
private static final String SNAPSHOT = "snapshot";
@SuppressWarnings("squid:S5164")
protected static final ThreadLocal<SimpleDateFormat> SNAPSHOT_SUFFIX_FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmm", Locale.ROOT));
private static final String NPM_REPOSITORY = "npmRepository";
private static final String NPM_NAME = "npmName";
private static final String NPM_VERSION = "npmVersion";
// NPM Option Values
protected String npmRepository = null;
protected String snapshot = null;
protected String npmName = null;
protected String npmVersion = "1.0.0";
protected String modelPropertyNaming = "camelCase";
protected HashSet<String> languageGenericTypes;
public TypeScriptClientCodegen() {
super();
this.frameworkToHttpLibMap = new HashMap<>();
this.frameworkToHttpLibMap.put("fetch-api", "isomorphic-fetch");
this.frameworkToHttpLibMap.put("jquery", "jquery");
this.generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata).stability(Stability.EXPERIMENTAL).build();
// clear import mapping (from default generator) as TS does not use it
// at the moment
importMapping.clear();
outputFolder = "generated-code" + File.separator + "typescript";
embeddedTemplateDir = templateDir = "typescript";
supportsInheritance = true;
// NOTE: TypeScript uses camel cased reserved words, while models are title cased. We don't want lowercase comparisons.
reservedWords.addAll(Arrays.asList(
// local variable names used in API methods (endpoints)
"varLocalPath", "queryParameters", "headerParams", "formParams", "useFormData", "varLocalDeferred",
"requestOptions",
// Typescript reserved words
"abstract", "await", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with", "yield"));
languageSpecificPrimitives = new HashSet<>(Arrays.asList(
"string",
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"Object",
"Array",
"Date",
"number",
"any",
"File",
"Error",
"Map"
));
languageGenericTypes = new HashSet<String>(Arrays.asList(
"Array"
));
instantiationTypes.put("array", "Array");
typeMapping = new HashMap<String, String>();
typeMapping.put("Array", "Array");
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("boolean", "boolean");
typeMapping.put("string", "string");
typeMapping.put("int", "number");
typeMapping.put("float", "number");
typeMapping.put("number", "number");
typeMapping.put("long", "number");
typeMapping.put("short", "number");
typeMapping.put("char", "string");
typeMapping.put("double", "number");
typeMapping.put("object", "any");
typeMapping.put("integer", "number");
typeMapping.put("Map", "any");
typeMapping.put("date", "string");
typeMapping.put("DateTime", "Date");
typeMapping.put("binary", "any");
typeMapping.put("File", "any");
typeMapping.put("ByteArray", "string");
typeMapping.put("UUID", "string");
typeMapping.put("Error", "Error");
cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package." +
" Required to generate a full package"));
cliOptions.add(new CliOption(NPM_VERSION, "The version of your npm package. If not provided, using the version from the OpenAPI specification file.").defaultValue(this.getNpmVersion()));
cliOptions.add(new CliOption(NPM_REPOSITORY, "Use this property to set an url your private npmRepo in the package.json"));
cliOptions.add(CliOption.newBoolean(SNAPSHOT,
"When setting this property to true, the version will be suffixed with -SNAPSHOT." + this.SNAPSHOT_SUFFIX_FORMAT.get().toPattern(),
false));
cliOptions.add(new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, CodegenConstants.MODEL_PROPERTY_NAMING_DESC).defaultValue("camelCase"));
cliOptions.add(new CliOption(CodegenConstants.SUPPORTS_ES6, CodegenConstants.SUPPORTS_ES6_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.FILE_CONTENT_DATA_TYPE, TypeScriptClientCodegen.FILE_CONTENT_DATA_TYPE_DESC).defaultValue("Buffer"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_RXJS_SWITCH, TypeScriptClientCodegen.USE_RXJS_SWITCH_DESC).defaultValue("false"));
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_OBJECT_PARAMS_SWITCH, TypeScriptClientCodegen.USE_OBJECT_PARAMS_SWITCH).defaultValue("false"));
CliOption frameworkOption = new CliOption(TypeScriptClientCodegen.FRAMEWORK_SWITCH, TypeScriptClientCodegen.FRAMEWORK_SWITCH_DESC);
for (String option: TypeScriptClientCodegen.FRAMEWORKS) {
frameworkOption.addEnum(option, option);
}
frameworkOption.defaultValue(FRAMEWORKS[0]);
cliOptions.add(frameworkOption);
CliOption platformOption = new CliOption(TypeScriptClientCodegen.PLATFORM_SWITCH, TypeScriptClientCodegen.PLATFORM_SWITCH_DESC);
for (String option: TypeScriptClientCodegen.PLATFORMS) {
platformOption.addEnum(option, option);
}
platformOption.defaultValue(PLATFORMS[0]);
cliOptions.add(platformOption);
//Documentation
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("package.mustache", "", "package.json"));
supportingFiles.add(new SupportingFile("tsconfig.mustache", "", "tsconfig.json"));
supportingFiles.add(new SupportingFile(".gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
// Util
supportingFiles.add(new SupportingFile("util.mustache", "", "util.ts"));
supportingFiles.add(new SupportingFile("api" + File.separator + "exception.mustache", "apis", "exception.ts"));
// http
supportingFiles.add(new SupportingFile("http" + File.separator + "http.mustache", "http", "http.ts"));
supportingFiles.add(new SupportingFile("http" + File.separator + "servers.mustache", "servers.ts"));
supportingFiles.add(new SupportingFile("configuration.mustache", "", "configuration.ts"));
supportingFiles.add(new SupportingFile("auth" + File.separator + "auth.mustache", "auth", "auth.ts"));
supportingFiles.add(new SupportingFile("model" + File.separator + "models_all.mustache", "models", "all.ts"));
supportingFiles.add(new SupportingFile("types" + File.separator + "PromiseAPI.mustache", "types", "PromiseAPI.ts"));
supportingFiles.add(new SupportingFile("types" + File.separator + "ObservableAPI.mustache", "types", "ObservableAPI.ts"));
supportingFiles.add(new SupportingFile("types" + File.separator + "ObjectParamAPI.mustache", "types", "ObjectParamAPI.ts"));
// models
this.setModelPackage("");
supportingFiles.add(new SupportingFile("model" + File.separator + "ObjectSerializer.mustache", "models", "ObjectSerializer.ts"));
modelTemplateFiles.put("model" + File.separator + "model.mustache", ".ts");
// api
this.setApiPackage("");
supportingFiles.add(new SupportingFile("api" + File.separator + "middleware.mustache", "", "middleware.ts"));
this.supportingFiles.add(new SupportingFile("api" + File.separator + "baseapi.mustache", "apis", "baseapi.ts"));
this.apiTemplateFiles.put("api" + File.separator + "api.mustache", ".ts");
}
public String getNpmName() {
return npmName;
}
public void setNpmName(String npmName) {
this.npmName = npmName;
}
public String getNpmRepository() {
return npmRepository;
}
public void setNpmRepository(String npmRepository) {
this.npmRepository = npmRepository;
}
public String getNpmVersion() {
return npmVersion;
}
public void setNpmVersion(String npmVersion) {
this.npmVersion = npmVersion;
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public void preprocessOpenAPI(OpenAPI openAPI) {
if (additionalProperties.containsKey(NPM_NAME)) {
// If no npmVersion is provided in additional properties, version from API specification is used.
// If none of them is provided then fallbacks to default version
if (additionalProperties.containsKey(NPM_VERSION)) {
this.setNpmVersion(additionalProperties.get(NPM_VERSION).toString());
} else if (openAPI.getInfo() != null && openAPI.getInfo().getVersion() != null) {
this.setNpmVersion(openAPI.getInfo().getVersion());
}
if (additionalProperties.containsKey(SNAPSHOT) && Boolean.parseBoolean(additionalProperties.get(SNAPSHOT).toString())) {
if (npmVersion.toUpperCase(Locale.ROOT).matches("^.*-SNAPSHOT$")) {
this.setNpmVersion(npmVersion + "." + SNAPSHOT_SUFFIX_FORMAT.get().format(new Date()));
} else {
this.setNpmVersion(npmVersion + "-SNAPSHOT." + SNAPSHOT_SUFFIX_FORMAT.get().format(new Date()));
}
}
additionalProperties.put(NPM_VERSION, npmVersion);
}
}
@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
final Object propFramework = additionalProperties.get(FRAMEWORK_SWITCH);
Map<String, Boolean> frameworks = new HashMap<>();
for (String framework: FRAMEWORKS) {
frameworks.put(framework, framework.equals(propFramework));
}
objs.put("framework", propFramework);
objs.put("frameworks", frameworks);
objs.put("fileContentDataType", additionalProperties.get(FILE_CONTENT_DATA_TYPE));
return objs;
}
@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> operations, List<Object> models) {
// Add additional filename information for model imports in the apis
List<Map<String, Object>> imports = (List<Map<String, Object>>) operations.get("imports");
for (Map<String, Object> im : imports) {
im.put("filename", ((String) im.get("import")).replace(".", File.separator));
im.put("classname", getModelnameFromModelFilename(im.get("import").toString()));
}
@SuppressWarnings("unchecked")
Map<String, Object> operationsMap = (Map<String, Object>) operations.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operationsMap.get("operation");
for (CodegenOperation operation: operationList) {
List<CodegenResponse> responses = operation.responses;
operation.returnType = this.getReturnType(responses);
}
return operations;
}
/**
* Returns the correct return type based on all 2xx HTTP responses defined for an operation.
* @param responses all CodegenResponses defined for one operation
* @return TypeScript return type
*/
private String getReturnType(List<CodegenResponse> responses) {
Set<String> returnTypes = new HashSet<String>();
for (CodegenResponse response: responses) {
if (response.is2xx) {
if (response.dataType != null) {
returnTypes.add(response.dataType);
} else {
returnTypes.add("void");
}
}
}
if (returnTypes.size() == 0) {
return null;
}
return String.join(" | ", returnTypes);
}
private String getModelnameFromModelFilename(String filename) {
String name = filename.substring((modelPackage() + File.separator).length());
return camelize(name);
}
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@Override
public String toParamName(String name) {
// should be the same as variable name
return toVarName(name);
}
@Override
public String toVarName(String name) {
// sanitize name
name = sanitizeName(name);
if ("_".equals(name)) {
name = "_u";
}
// 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;
}
@Override
public String toModelName(String name) {
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
if (!StringUtils.isEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
name = name + "_" + modelNameSuffix;
}
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(name)) {
String modelName = camelize("model_" + name);
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + modelName);
return modelName;
}
// model name starts with number
if (name.matches("^\\d.*")) {
String modelName = camelize("model_" + name); // e.g. 200Response => Model200Response (after camelize)
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + modelName);
return modelName;
}
if (languageSpecificPrimitives.contains(name)) {
String modelName = camelize("model_" + name);
LOGGER.warn(name + " (model name matches existing language type) cannot be used as a model name. Renamed to " + modelName);
return modelName;
}
// camelize the model name
// phone_number => PhoneNumber
return camelize(name);
}
@Override
public String toModelFilename(String name) {
// should be the same as the model name
return toModelName(name);
}
@Override
protected String getParameterDataType(Parameter parameter, Schema p) {
// handle enums of various data types
Schema inner;
if (ModelUtils.isArraySchema(p)) {
ArraySchema mp1 = (ArraySchema) p;
inner = mp1.getItems();
return this.getSchemaType(p) + "<" + this.getParameterDataType(parameter, inner) + ">";
} else if (ModelUtils.isMapSchema(p)) {
inner = (Schema) p.getAdditionalProperties();
return "{ [key: string]: " + this.getParameterDataType(parameter, inner) + "; }";
} else if (ModelUtils.isStringSchema(p)) {
// Handle string enums
if (p.getEnum() != null) {
return enumValuesToEnumTypeUnion(p.getEnum(), "string");
}
} else if (ModelUtils.isIntegerSchema(p)) {
// Handle integer enums
if (p.getEnum() != null) {
return numericEnumValuesToEnumTypeUnion(new ArrayList<Number>(p.getEnum()));
}
} else if (ModelUtils.isNumberSchema(p)) {
// Handle double enums
if (p.getEnum() != null) {
return numericEnumValuesToEnumTypeUnion(new ArrayList<Number>(p.getEnum()));
}
}
return this.getTypeDeclaration(p);
}
/**
* Converts a list of strings to a literal union for representing enum values as a type.
* Example output: 'available' | 'pending' | 'sold'
*
* @param values list of allowed enum values
* @param dataType either "string" or "number"
* @return a literal union for representing enum values as a type
*/
protected String enumValuesToEnumTypeUnion(List<String> values, String dataType) {
StringBuilder b = new StringBuilder();
boolean isFirst = true;
for (String value : values) {
if (!isFirst) {
b.append(" | ");
}
b.append(toEnumValue(value.toString(), dataType));
isFirst = false;
}
return b.toString();
}
/**
* Converts a list of numbers to a literal union for representing enum values as a type.
* Example output: 3 | 9 | 55
*
* @param values a list of numbers
* @return a literal union for representing enum values as a type
*/
protected String numericEnumValuesToEnumTypeUnion(List<Number> values) {
List<String> stringValues = new ArrayList<>();
for (Number value : values) {
stringValues.add(value.toString());
}
return enumValuesToEnumTypeUnion(stringValues, "number");
}
@Override
public String toDefaultValue(Schema p) {
if (ModelUtils.isBooleanSchema(p)) {
return UNDEFINED_VALUE;
} else if (ModelUtils.isDateSchema(p)) {
return UNDEFINED_VALUE;
} else if (ModelUtils.isDateTimeSchema(p)) {
return UNDEFINED_VALUE;
} else if (ModelUtils.isNumberSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
return UNDEFINED_VALUE;
} else if (ModelUtils.isIntegerSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
return UNDEFINED_VALUE;
} else if (ModelUtils.isStringSchema(p)) {
if (p.getDefault() != null) {
return "'" + (String) p.getDefault() + "'";
}
return UNDEFINED_VALUE;
} else {
return UNDEFINED_VALUE;
}
}
@Override
protected boolean isReservedWord(String word) {
// NOTE: This differs from super's implementation in that TypeScript does _not_ want case insensitive matching.
return reservedWords.contains(word);
}
@Override
public String getSchemaType(Schema p) {
String openAPIType = super.getSchemaType(p);
String type = null;
if (typeMapping.containsKey(openAPIType)) {
type = typeMapping.get(openAPIType);
if (languageSpecificPrimitives.contains(type))
return type;
} else
type = openAPIType;
return toModelName(type);
}
@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException("Empty method name (operationId) not allowed");
}
// method name cannot use reserved keyword, e.g. return
// append _ at the beginning, e.g. _return
if (isReservedWord(operationId)) {
return escapeReservedWord(camelize(sanitizeName(operationId), true));
}
return camelize(sanitizeName(operationId), true);
}
public void setModelPropertyNaming(String naming) {
if ("original".equals(naming) || "camelCase".equals(naming) ||
"PascalCase".equals(naming) || "snake_case".equals(naming)) {
this.modelPropertyNaming = naming;
} else {
throw new IllegalArgumentException("Invalid model property naming '" +
naming + "'. Must be 'original', 'camelCase', " +
"'PascalCase' or 'snake_case'");
}
}
public String getModelPropertyNaming() {
return this.modelPropertyNaming;
}
public String getNameUsingModelPropertyNaming(String name) {
switch (CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.valueOf(getModelPropertyNaming())) {
case original:
return name;
case camelCase:
return camelize(name, 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'");
}
}
@Override
public String toEnumValue(String value, String datatype) {
if ("number".equals(datatype)) {
return value;
} else {
return "\'" + escapeText(value) + "\'";
}
}
@Override
public String toEnumDefaultValue(String value, String datatype) {
return datatype + "_" + value;
}
@Override
public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "Empty";
}
// for symbol, e.g. $, #
if (getSymbolName(name) != null) {
return camelize(getSymbolName(name));
}
// number
if ("number".equals(datatype)) {
String varName = "NUMBER_" + name;
varName = varName.replaceAll("-", "MINUS_");
varName = varName.replaceAll("\\+", "PLUS_");
varName = varName.replaceAll("\\.", "_DOT_");
return varName;
}
// string
String enumName = sanitizeName(name);
enumName = enumName.replaceFirst("^_", "");
enumName = enumName.replaceFirst("_$", "");
// camelize the enum variable name
// ref: https://basarat.gitbooks.io/typescript/content/docs/enums.html
enumName = camelize(enumName);
if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName;
} else {
return enumName;
}
}
@Override
public String toEnumName(CodegenProperty property) {
String enumName = toModelName(property.name) + "Enum";
if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName;
} else {
return enumName;
}
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
// process enum in models
List<Map<String, Object>> models = (List<Map<String, Object>>) postProcessModelsEnum(objs).get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
cm.imports = new TreeSet(cm.imports);
// name enum with model name, e.g. StatusEnum => Pet.StatusEnum
for (CodegenProperty var : cm.vars) {
if (Boolean.TRUE.equals(var.isEnum)) {
var.datatypeWithEnum = var.datatypeWithEnum.replace(var.enumName, cm.classname + var.enumName);
}
}
if (cm.parent != null) {
for (CodegenProperty var : cm.allVars) {
if (Boolean.TRUE.equals(var.isEnum)) {
var.datatypeWithEnum = var.datatypeWithEnum
.replace(var.enumName, cm.classname + var.enumName);
}
}
}
}
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
// Add additional filename information for imports
mo.put("tsImports", toTsImports(cm, cm.imports));
}
return objs;
}
private List<Map<String, String>> toTsImports(CodegenModel cm, Set<String> imports) {
List<Map<String, String>> tsImports = new ArrayList<>();
for (String im : imports) {
if (!im.equals(cm.classname)) {
HashMap<String, String> tsImport = new HashMap<>();
// TVG: This is used as class name in the import statements of the model file
tsImport.put("classname", im);
tsImport.put("filename", toModelFilename(im));
tsImports.add(tsImport);
}
}
return tsImports;
}
@Override
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
Map<String, Object> result = super.postProcessAllModels(objs);
for (Map.Entry<String, Object> entry : result.entrySet()) {
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
if (cm.discriminator != null && cm.children != null) {
for (CodegenModel child : cm.children) {
this.setDiscriminatorValue(child, cm.discriminator.getPropertyName(), this.getDiscriminatorValue(child));
}
}
}
}
return result;
}
private void setDiscriminatorValue(CodegenModel model, String baseName, String value) {
for (CodegenProperty prop : model.allVars) {
if (prop.baseName.equals(baseName)) {
prop.discriminatorValue = value;
}
}
if (model.children != null) {
final boolean newDiscriminator = model.discriminator != null;
for (CodegenModel child : model.children) {
this.setDiscriminatorValue(child, baseName, newDiscriminator ? value : this.getDiscriminatorValue(child));
}
}
}
private String getDiscriminatorValue(CodegenModel model) {
return model.vendorExtensions.containsKey(X_DISCRIMINATOR_TYPE) ?
(String) model.vendorExtensions.get(X_DISCRIMINATOR_TYPE) : model.classname;
}
@Override
public String escapeQuotationMark(String input) {
// remove ', " to avoid code injection
return input.replace("\"", "").replace("'", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String getName() {
return "typescript";
}
@Override
public String getHelp() {
return "Generates a TypeScript client library using Fetch API (beta).";
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.MODEL_PROPERTY_NAMING)) {
setModelPropertyNaming((String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING));
}
convertPropertyToBooleanAndWriteBack(CodegenConstants.SUPPORTS_ES6);
// change package names
apiPackage = this.apiPackage + ".apis";
modelPackage = this.modelPackage + ".models";
testPackage = this.testPackage + ".tests";
additionalProperties.putIfAbsent(FRAMEWORK_SWITCH, FRAMEWORKS[0]);
supportingFiles.add(new SupportingFile("index.mustache", "index.ts"));
String httpLibName = this.getHttpLibForFramework(additionalProperties.get(FRAMEWORK_SWITCH).toString());
supportingFiles.add(new SupportingFile(
"http" + File.separator + httpLibName + ".mustache",
"http", httpLibName + ".ts"
));
Object propPlatform = additionalProperties.get(PLATFORM_SWITCH);
if (propPlatform == null) {
propPlatform = "browser";
additionalProperties.put("platform", propPlatform);
}
Map<String, Boolean> platforms = new HashMap<>();
for (String platform: PLATFORMS) {
platforms.put(platform, platform.equals(propPlatform));
}
additionalProperties.put("platforms", platforms);
additionalProperties.putIfAbsent(FILE_CONTENT_DATA_TYPE, propPlatform.equals("node") ? "Buffer" : "Blob");
final boolean useRxJS = convertPropertyToBooleanAndWriteBack(USE_RXJS_SWITCH);
if (!useRxJS) {
supportingFiles.add(new SupportingFile("rxjsStub.mustache", "rxjsStub.ts"));
}
// NPM Settings
if (additionalProperties.containsKey(NPM_NAME)) {
setNpmName(additionalProperties.get(NPM_NAME).toString());
}
if (additionalProperties.containsKey(NPM_VERSION)) {
setNpmVersion(additionalProperties.get(NPM_VERSION).toString());
}
if (additionalProperties.containsKey(NPM_REPOSITORY)) {
setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString());
}
}
private String getHttpLibForFramework(String object) {
return this.frameworkToHttpLibMap.get(object);
}
@Override
public String getTypeDeclaration(Schema p) {
Schema inner;
if (ModelUtils.isArraySchema(p)) {
inner = ((ArraySchema) p).getItems();
return this.getSchemaType(p) + "<" + this.getTypeDeclaration(inner) + ">";
} else if (ModelUtils.isMapSchema(p)) {
inner = (Schema) p.getAdditionalProperties();
return "{ [key: string]: " + this.getTypeDeclaration(inner) + "; }";
} else if (ModelUtils.isFileSchema(p)) {
return "HttpFile";
} else if (ModelUtils.isBinarySchema(p)) {
return "any";
} else {
return super.getTypeDeclaration(p);
}
}
@Override
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) {
codegenModel.additionalPropertiesType = getTypeDeclaration((Schema) schema.getAdditionalProperties());
addImport(codegenModel, codegenModel.additionalPropertiesType);
}
}

View File

@@ -23,6 +23,7 @@ import org.springframework.context.annotation.Configuration;
{{#isOAuth}}
import org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
{{#isApplication}}
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
{{/isApplication}}
@@ -71,8 +72,14 @@ public class ClientConfiguration {
{{#isOAuth}}
@Bean
@ConditionalOnProperty("{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}.client-id")
public OAuth2FeignRequestInterceptor {{{name}}}RequestInterceptor() {
return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(), {{{name}}}ResourceDetails());
public OAuth2FeignRequestInterceptor {{{name}}}RequestInterceptor(OAuth2ClientContext oAuth2ClientContext) {
return new OAuth2FeignRequestInterceptor(oAuth2ClientContext, {{{name}}}ResourceDetails());
}
@Bean
@ConditionalOnProperty("{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}.client-id")
public OAuth2ClientContext oAuth2ClientContext() {
return new DefaultOAuth2ClientContext();
}
{{#isCode}}

View File

@@ -116,7 +116,6 @@ org.openapitools.codegen.languages.StaticHtmlGenerator
org.openapitools.codegen.languages.StaticHtml2Generator
org.openapitools.codegen.languages.Swift4Codegen
org.openapitools.codegen.languages.Swift5ClientCodegen
org.openapitools.codegen.languages.TypeScriptClientCodegen
org.openapitools.codegen.languages.TypeScriptAngularClientCodegen
org.openapitools.codegen.languages.TypeScriptAngularJsClientCodegen
org.openapitools.codegen.languages.TypeScriptAureliaClientCodegen

View File

@@ -15,5 +15,6 @@ public class {{unrealModuleName}} : ModuleRules
"Json",
}
);
PCHUsage = PCHUsageMode.NoPCHs;
}
}

View File

@@ -52,7 +52,7 @@ public:
{{#responses.0}}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
{{/responses.0}}
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
{{#returnType}}{{{returnType}}} Content;{{/returnType}}
};

View File

@@ -6,6 +6,7 @@
#include "Serialization/JsonSerializer.h"
#include "Dom/JsonObject.h"
#include "Misc/Base64.h"
#include "PlatformHttp.h"
class IHttpRequest;
@@ -196,10 +197,22 @@ inline FString CollectionToUrlString_multi(const TArray<T>& Collection, const TC
//////////////////////////////////////////////////////////////////////////
template<typename T, typename std::enable_if<!std::is_base_of<Model, T>::value, int>::type = 0>
inline void WriteJsonValue(JsonWriter& Writer, const T& Value)
inline void WriteJsonValue(JsonWriter& Writer, const TSharedPtr<FJsonObject>& Value)
{
Writer->WriteValue(Value);
if (Value.IsValid())
{
FJsonSerializer::Serialize(Value.ToSharedRef(), Writer, false);
}
else
{
Writer->WriteObjectStart();
Writer->WriteObjectEnd();
}
}
inline void WriteJsonValue(JsonWriter& Writer, const TArray<uint8>& Value)
{
Writer->WriteValue(ToString(Value));
}
inline void WriteJsonValue(JsonWriter& Writer, const FDateTime& Value)
@@ -212,6 +225,12 @@ inline void WriteJsonValue(JsonWriter& Writer, const Model& Value)
Value.WriteJson(Writer);
}
template<typename T, typename std::enable_if<!std::is_base_of<Model, T>::value, int>::type = 0>
inline void WriteJsonValue(JsonWriter& Writer, const T& Value)
{
Writer->WriteValue(Value);
}
template<typename T>
inline void WriteJsonValue(JsonWriter& Writer, const TArray<T>& Value)
{
@@ -235,54 +254,8 @@ inline void WriteJsonValue(JsonWriter& Writer, const TMap<FString, T>& Value)
Writer->WriteObjectEnd();
}
inline void WriteJsonValue(JsonWriter& Writer, const TSharedPtr<FJsonObject>& Value)
{
if (Value.IsValid())
{
FJsonSerializer::Serialize(Value.ToSharedRef(), Writer, false);
}
else
{
Writer->WriteObjectStart();
Writer->WriteObjectEnd();
}
}
inline void WriteJsonValue(JsonWriter& Writer, const TArray<uint8>& Value)
{
Writer->WriteValue(ToString(Value));
}
//////////////////////////////////////////////////////////////////////////
template<typename T>
inline bool TryGetJsonValue(const TSharedPtr<FJsonObject>& JsonObject, const FString& Key, T& Value)
{
const TSharedPtr<FJsonValue> JsonValue = JsonObject->TryGetField(Key);
if (JsonValue.IsValid() && !JsonValue->IsNull())
{
return TryGetJsonValue(JsonValue, Value);
}
return false;
}
template<typename T>
inline bool TryGetJsonValue(const TSharedPtr<FJsonObject>& JsonObject, const FString& Key, TOptional<T>& OptionalValue)
{
if(JsonObject->HasField(Key))
{
T Value;
if (TryGetJsonValue(JsonObject, Key, Value))
{
OptionalValue = Value;
return true;
}
else
return false;
}
return true; // Absence of optional value is not a parsing error
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, FString& Value)
{
FString TmpValue;
@@ -316,6 +289,34 @@ inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, bool& Value
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, TSharedPtr<FJsonObject>& JsonObjectValue)
{
const TSharedPtr<FJsonObject>* Object;
if (JsonValue->TryGetObject(Object))
{
JsonObjectValue = *Object;
return true;
}
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, TArray<uint8>& Value)
{
FString TmpValue;
if (JsonValue->TryGetString(TmpValue))
{
Base64UrlDecode(TmpValue, Value);
return true;
}
else
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, Model& Value)
{
return Value.FromJson(JsonValue);
}
template<typename T, typename std::enable_if<!std::is_base_of<Model, T>::value, int>::type = 0>
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, T& Value)
{
@@ -329,15 +330,6 @@ inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, T& Value)
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, Model& Value)
{
const TSharedPtr<FJsonObject>* Object;
if (JsonValue->TryGetObject(Object))
return Value.FromJson(*Object);
else
return false;
}
template<typename T>
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, TArray<T>& ArrayValue)
{
@@ -377,27 +369,32 @@ inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, TMap<FStrin
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, TSharedPtr<FJsonObject>& JsonObjectValue)
template<typename T>
inline bool TryGetJsonValue(const TSharedPtr<FJsonObject>& JsonObject, const FString& Key, T& Value)
{
const TSharedPtr<FJsonObject>* Object;
if (JsonValue->TryGetObject(Object))
const TSharedPtr<FJsonValue> JsonValue = JsonObject->TryGetField(Key);
if (JsonValue.IsValid() && !JsonValue->IsNull())
{
JsonObjectValue = *Object;
return true;
return TryGetJsonValue(JsonValue, Value);
}
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, TArray<uint8>& Value)
template<typename T>
inline bool TryGetJsonValue(const TSharedPtr<FJsonObject>& JsonObject, const FString& Key, TOptional<T>& OptionalValue)
{
FString TmpValue;
if (JsonValue->TryGetString(TmpValue))
if(JsonObject->HasField(Key))
{
Base64UrlDecode(TmpValue, Value);
return true;
T Value;
if (TryGetJsonValue(JsonObject, Key, Value))
{
OptionalValue = Value;
return true;
}
else
return false;
}
else
return false;
return true; // Absence of optional value is not a parsing error
}
{{#cppNamespaceDeclarations}}

View File

@@ -6,6 +6,7 @@
#include "Interfaces/IHttpRequest.h"
#include "PlatformHttp.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
{{#cppNamespaceDeclarations}}
namespace {{this}}

View File

@@ -18,7 +18,7 @@ class {{dllapi}} Model
public:
virtual ~Model() {}
virtual void WriteJson(JsonWriter& Writer) const = 0;
virtual bool FromJson(const TSharedPtr<FJsonObject>& JsonObject) = 0;
virtual bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) = 0;
};
class {{dllapi}} Request
@@ -33,7 +33,7 @@ class {{dllapi}} Response
{
public:
virtual ~Response() {}
virtual bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) = 0;
virtual bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) = 0;
void SetSuccessful(bool InSuccessful) { Successful = InSuccessful; }
bool IsSuccessful() const { return Successful; }

View File

@@ -21,9 +21,26 @@ class {{dllapi}} {{classname}} : public Model
{
public:
virtual ~{{classname}}() {}
bool FromJson(const TSharedPtr<FJsonObject>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
void WriteJson(JsonWriter& Writer) const final;
{{#isString}}
{{#isEnum}}
{{#allowableValues}}
enum class Values
{
{{#enumVars}}
{{name}},
{{/enumVars}}
};
Values Value{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}};
{{/allowableValues}}
{{/isEnum}}
{{^isEnum}}
FString Value{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}};
{{/isEnum}}
{{/isString}}
{{#vars}}
{{#isEnum}}
{{#allowableValues}}

View File

@@ -11,6 +11,54 @@ namespace {{this}}
{
{{/cppNamespaceDeclarations}}
{{#models}}{{#model}}
{{#isEnum}}
inline FString ToString(const {{classname}}::Values& Value)
{
{{#allowableValues}}
switch (Value)
{
{{#enumVars}}
case {{classname}}::Values::{{name}}:
return TEXT({{{value}}});
{{/enumVars}}
}
{{/allowableValues}}
UE_LOG(Log{{unrealModuleName}}, Error, TEXT("Invalid {{classname}}::Values Value (%d)"), (int)Value);
return TEXT("");
}
inline FStringFormatArg ToStringFormatArg(const {{classname}}::Values& Value)
{
return FStringFormatArg(ToString(Value));
}
inline void WriteJsonValue(JsonWriter& Writer, const {{classname}}::Values& Value)
{
WriteJsonValue(Writer, ToString(Value));
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, {{classname}}::Values& Value)
{
{{#allowableValues}}
FString TmpValue;
if (JsonValue->TryGetString(TmpValue))
{
static TMap<FString, {{classname}}::Values> StringToEnum = { {{#enumVars}}
{ TEXT({{{value}}}), {{classname}}::Values::{{name}} },{{/enumVars}} };
const auto Found = StringToEnum.Find(TmpValue);
if(Found)
{
Value = *Found;
return true;
}
}
{{/allowableValues}}
return false;
}
{{/isEnum}}
{{#hasEnums}}
{{#vars}}
{{#isEnum}}
@@ -65,9 +113,10 @@ inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, {{classname
{{/hasEnums}}
void {{classname}}::WriteJson(JsonWriter& Writer) const
{
{{#parent}}
#error inheritance not handled right now
{{/parent}}
{{#isString}}
WriteJsonValue(Writer, Value);
{{/isString}}
{{^isString}}
Writer->WriteObjectStart();
{{#vars}}
{{#required}}
@@ -81,18 +130,29 @@ void {{classname}}::WriteJson(JsonWriter& Writer) const
{{/required}}
{{/vars}}
Writer->WriteObjectEnd();
{{/isString}}
}
bool {{classname}}::FromJson(const TSharedPtr<FJsonObject>& JsonObject)
bool {{classname}}::FromJson(const TSharedPtr<FJsonValue>& JsonValue)
{
{{#isString}}
return TryGetJsonValue(JsonValue, Value);
{{/isString}}
{{^isString}}
const TSharedPtr<FJsonObject>* Object;
if (!JsonValue->TryGetObject(Object))
return false;
bool ParseSuccess = true;
{{#vars}}
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("{{baseName}}"), {{name}});
ParseSuccess &= TryGetJsonValue(*Object, TEXT("{{baseName}}"), {{name}});
{{/vars}}
return ParseSuccess;
{{/isString}}
}
{{/model}}
{{/models}}
{{#cppNamespaceDeclarations}}

View File

@@ -15,6 +15,35 @@ func (dst *{{classname}}) UnmarshalJSON(data []byte) error {
}
{{/isNullable}}
{{#discriminator}}
{{#mappedModels}}
{{#-first}}
// use discriminator value to speed up the lookup
var jsonDict map[string]interface{}
err := json.Unmarshal(data, &jsonDict)
if err != nil {
return fmt.Errorf("Failed to unmarshal JSON into map for the discrimintor lookup.")
}
{{/-first}}
// check if the discriminator value is '{{{mappingName}}}'
if jsonDict["{{{propertyBaseName}}}"] == "{{{mappingName}}}" {
// try to unmarshal JSON data into {{{modelName}}}
err = json.Unmarshal(data, &dst.{{{modelName}}});
if err == nil {
json{{{modelName}}}, _ := json.Marshal(dst.{{{modelName}}})
if string(json{{{modelName}}}) == "{}" { // empty struct
dst.{{{modelName}}} = nil
} else {
return nil // data stored in dst.{{{modelName}}}, return on the first match
}
} else {
dst.{{{modelName}}} = nil
}
}
{{/mappedModels}}
{{/discriminator}}
{{#anyOf}}
// try to unmarshal JSON data into {{{.}}}
err = json.Unmarshal(data, &dst.{{{.}}});
@@ -44,4 +73,4 @@ func (src *{{classname}}) MarshalJSON() ([]byte, error) {
return nil, nil // no data in anyOf schemas
}
{{>nullable_model}}
{{>nullable_model}}

View File

@@ -24,9 +24,40 @@ func (dst *{{classname}}) UnmarshalJSON(data []byte) error {
}
{{/isNullable}}
{{#useOneOfDiscriminatorLookup}}
{{#discriminator}}
{{#mappedModels}}
{{#-first}}
// use discriminator value to speed up the lookup
var jsonDict map[string]interface{}
err = json.Unmarshal(data, &jsonDict)
if err != nil {
return fmt.Errorf("Failed to unmarshal JSON into map for the discrimintor lookup.")
}
{{/-first}}
// check if the discriminator value is '{{{mappingName}}}'
if jsonDict["{{{propertyBaseName}}}"] == "{{{mappingName}}}" {
// try to unmarshal JSON data into {{{modelName}}}
err = json.Unmarshal(data, &dst.{{{modelName}}})
if err == nil {
json{{{modelName}}}, _ := json.Marshal(dst.{{{modelName}}})
if string(json{{{modelName}}}) == "{}" { // empty struct
dst.{{{modelName}}} = nil
} else {
return nil // data stored in dst.{{{modelName}}}, return on the first match
}
} else {
dst.{{{modelName}}} = nil
}
}
{{/mappedModels}}
{{/discriminator}}
{{/useOneOfDiscriminatorLookup}}
{{#oneOf}}
// try to unmarshal data into {{{.}}}
err = json.Unmarshal(data, &dst.{{{.}}});
err = json.Unmarshal(data, &dst.{{{.}}})
if err == nil {
json{{{.}}}, _ := json.Marshal(dst.{{{.}}})
if string(json{{{.}}}) == "{}" { // empty struct
@@ -76,4 +107,4 @@ func (obj *{{classname}}) GetActualInstance() (interface{}) {
return nil
}
{{>nullable_model}}
{{>nullable_model}}

View File

@@ -13,8 +13,15 @@ type {{classname}} struct {
{{/description}}
{{name}} {{^required}}{{^isNullable}}*{{/isNullable}}{{/required}}{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
{{/vars}}
{{#vendorExtensions.x-additional-properties}}
AdditionalProperties map[string]interface{}
{{/vendorExtensions.x-additional-properties}}
}
{{#vendorExtensions.x-additional-properties}}
type _{{{classname}}} {{{classname}}}
{{/vendorExtensions.x-additional-properties}}
// New{{classname}} instantiates a new {{classname}} object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
@@ -246,7 +253,35 @@ func (o {{classname}}) MarshalJSON() ([]byte, error) {
}
{{/isNullable}}
{{/vars}}
{{#vendorExtensions.x-additional-properties}}
for key, value := range o.AdditionalProperties {
toSerialize[key] = value
}
{{/vendorExtensions.x-additional-properties}}
return json.Marshal(toSerialize)
}
{{>nullable_model}}
{{#vendorExtensions.x-additional-properties}}
func (o *{{{classname}}}) UnmarshalJSON(bytes []byte) (err error) {
var{{{classname}}} := _{{{classname}}}{}
if err = json.Unmarshal(bytes, &var{{{classname}}}); err == nil {
*o = {{{classname}}}(var{{{classname}}})
}
additionalProperties := make(map[string]interface{})
if err = json.Unmarshal(bytes, &additionalProperties); err == nil {
{{#vars}}
delete(additionalProperties, "{{{baseName}}}")
{{/vars}}
o.AdditionalProperties = additionalProperties
}
return err
}
{{/vendorExtensions.x-additional-properties}}
{{>nullable_model}}

View File

@@ -48,9 +48,9 @@ import java.io.Serializable
){{/discriminator}}{{#parent}}{{^serializableModel}}{{^parcelizeModels}} : {{{parent}}}{{#isMapModel}}(){{/isMapModel}}{{#isArrayModel}}(){{/isArrayModel}}{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{#serializableModel}}{{^parcelizeModels}} : {{{parent}}}{{#isMapModel}}(){{/isMapModel}}{{#isArrayModel}}(){{/isArrayModel}}, Serializable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{^serializableModel}}{{#parcelizeModels}} : {{{parent}}}{{#isMapModel}}(){{/isMapModel}}{{#isArrayModel}}(){{/isArrayModel}}, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{#serializableModel}}{{#parcelizeModels}} : {{{parent}}}{{#isMapModel}}(){{/isMapModel}}{{#isArrayModel}}(){{/isArrayModel}}, Serializable, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{#serializableModel}}{{^parcelizeModels}} : Serializable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{#serializableModel}}{{#parcelizeModels}} : Serializable, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#vendorExtensions.x-has-data-class-body}} {
{{/vendorExtensions.x-has-data-class-body}}
{{#serializableModel}}
{{#nonPublicApi}}internal {{/nonPublicApi}}companion object {
private const val serialVersionUID: Long = 123
}
{{#nonPublicApi}}internal {{/nonPublicApi}}companion object {
private const val serialVersionUID: Long = 123
}
{{/serializableModel}}
{{#discriminator}}{{#vars}}{{#required}}
{{>interface_req_var}}{{/required}}{{^required}}

View File

@@ -47,11 +47,11 @@ import kotlinx.serialization.internal.CommonEnumSerializer
{{/enumVars}}{{/allowableValues}}
/**
This override toString avoids using the enum var name and uses the actual api value instead.
In cases the var name and value are different, the client would send incorrect enums to the server.
**/
override fun toString(): String {
/**
This override toString avoids using the enum var name and uses the actual api value instead.
In cases the var name and value are different, the client would send incorrect enums to the server.
**/
override fun toString(): String {
return value{{^isString}}.toString(){{/isString}}
}

View File

@@ -1 +1 @@
{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{#swaggerAnnotations}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{defaultValue}}}"{{/defaultValue}}) {{#useBeanValidation}}@Valid{{/useBeanValidation}}{{/swaggerAnnotations}} @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{paramName}}: {{>optionalDataType}}{{/isQueryParam}}
{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{#swaggerAnnotations}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/defaultValue}}) {{#useBeanValidation}}@Valid{{/useBeanValidation}}{{/swaggerAnnotations}} @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{#defaultValue}}, defaultValue={{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/defaultValue}}) {{paramName}}: {{>optionalDataType}}{{/isQueryParam}}

View File

@@ -5,8 +5,8 @@ Describe -tag '{{{packageName}}}' -name '{{{apiNamePrefix}}}{{{classname}}}' {
Context '{{{vendorExtensions.x-powershell-method-name}}}' {
It 'Test {{{vendorExtensions.x-powershell-method-name}}}' {
#$TestResult = Invoke-PetApiGetPetById{{#allParams}} -{{{paramName}}} "TEST_VALUE"{{/allParams}}
#$TestResult | Should BeOfType TODO
#$TestResult.property | Should Be 0
#$TestResult | Should -BeOfType TODO
#$TestResult.property | Should -Be 0
}
}

View File

@@ -38,6 +38,35 @@ function ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{classname}}} {
}
{{/isNullable}}
{{#discriminator}}
{{#mappedModels}}
{{#-first}}
$JsonData = ConvertFrom-Json -InputObject $Json
{{/-first}}
# check if the discriminator value is '{{{mappingName}}}'
if ($JsonData.PSobject.Properties["{{{propertyBaseName}}}"].value -eq "{{{mappingName}}}") {
# try to match {{{modelName}}} defined in the anyOf schemas
try {
$matchInstance = ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{modelName}}} $Json
foreach($property in $matchInstance.PsObject.Properties) {
if ($null -ne $property.Value) {
$matchType = "{{{modelName}}}"
return [PSCustomObject]@{
"ActualType" = ${matchType}
"ActualInstance" = ${matchInstance}
"anyOfSchemas" = @({{#anyOf}}"{{{.}}}"{{^-last}}, {{/-last}}{{/anyOf}})
}
}
}
} catch {
# fail to match the schema defined in anyOf with the discriminator lookup, proceed to the next one
Write-Debug "Failed to match '{{{modelName}}}' defined in anyOf ({{{apiNamePrefix}}}{{{classname}}}) using the discriminator lookup ({{{mappingName}}}). Proceeding with the typical anyOf type matching."
}
}
{{/mappedModels}}
{{/discriminator}}
{{#anyOf}}
if ($match -ne 0) { # no match yet
# try to match {{{.}}} defined in the anyOf schemas

View File

@@ -38,6 +38,37 @@ function ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{classname}}} {
}
{{/isNullable}}
{{#useOneOfDiscriminatorLookup}}
{{#discriminator}}
{{#mappedModels}}
{{#-first}}
$JsonData = ConvertFrom-Json -InputObject $Json
{{/-first}}
# check if the discriminator value is '{{{mappingName}}}'
if ($JsonData.PSobject.Properties["{{{propertyBaseName}}}"].value -eq "{{{mappingName}}}") {
# try to match {{{modelName}}} defined in the oneOf schemas
try {
$matchInstance = ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{modelName}}} $Json
foreach($property in $matchInstance.PsObject.Properties) {
if ($null -ne $property.Value) {
$matchType = "{{{modelName}}}"
return [PSCustomObject]@{
"ActualType" = ${matchType}
"ActualInstance" = ${matchInstance}
"oneOfSchemas" = @({{#oneOf}}"{{{.}}}"{{^-last}}, {{/-last}}{{/oneOf}})
}
}
}
} catch {
# fail to match the schema defined in oneOf with the discriminator lookup, proceed to the next one
Write-Debug "Failed to match '{{{modelName}}}' defined in oneOf ({{{apiNamePrefix}}}{{{classname}}}) using the discriminator lookup ({{{mappingName}}}). Proceeding with the typical oneOf type matching."
}
}
{{/mappedModels}}
{{/discriminator}}
{{/useOneOfDiscriminatorLookup}}
{{#oneOf}}
# try to match {{{.}}} defined in the oneOf schemas
try {

View File

@@ -129,13 +129,24 @@ function ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{classname}}} {
$PSBoundParameters | Out-DebugParameter | Write-Debug
$JsonParameters = ConvertFrom-Json -InputObject $Json
{{#vendorExtensions.x-additional-properties}}
${{{apiNamePrefix}}}{{{classname}}}AdditionalProperties = @{}
{{/vendorExtensions.x-additional-properties}}
# check if Json contains properties not defined in {{{apiNamePrefix}}}{{{classname}}}
$AllProperties = ({{#allVars}}"{{{baseName}}}"{{^-last}}, {{/-last}}{{/allVars}})
foreach ($name in $JsonParameters.PsObject.Properties.Name) {
{{^vendorExtensions.x-additional-properties}}
if (!($AllProperties.Contains($name))) {
throw "Error! JSON key '$name' not found in the properties: $($AllProperties)"
}
{{/vendorExtensions.x-additional-properties}}
{{#vendorExtensions.x-additional-properties}}
# store undefined properties in additionalProperties
if (!($AllProperties.Contains($name))) {
${{{apiNamePrefix}}}{{{classname}}}AdditionalProperties[$name] = $JsonParameters.PSobject.Properties[$name].value
}
{{/vendorExtensions.x-additional-properties}}
}
{{#requiredVars}}
@@ -166,6 +177,9 @@ function ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{classname}}} {
"<<baseName>>" = ${<<name>>}
<</allVars>>
<<={{ }}=>>
{{#vendorExtensions.x-additional-properties}}
"AdditionalProperties" = ${{{apiNamePrefix}}}{{{classname}}}AdditionalProperties
{{/vendorExtensions.x-additional-properties}}
}
return $PSO

View File

@@ -6,8 +6,8 @@ Describe -tag '{{{packageName}}}' -name '{{{apiNamePrefix}}}{{{classname}}}' {
It 'Initialize-{{{apiNamePrefix}}}{{{classname}}}' {
# a simple test to create an object
#$NewObject = Initialize-{{{apiNamePrefix}}}{{{classname}}}{{#vars}} -{{name}} "TEST_VALUE"{{/vars}}
#$NewObject | Should BeOfType {{classname}}
#$NewObject.property | Should Be 0
#$NewObject | Should -BeOfType {{classname}}
#$NewObject.property | Should -Be 0
}
}
}

View File

@@ -38,6 +38,7 @@ class {{classname}}(object):
{{/notes}}
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async_req=True
{{#sortParamsByRequiredFlag}}
>>> thread = api.{{operationId}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}async_req=True)
{{/sortParamsByRequiredFlag}}
@@ -46,20 +47,24 @@ class {{classname}}(object):
{{/sortParamsByRequiredFlag}}
>>> result = thread.get()
:param async_req bool: execute request asynchronously
{{#allParams}}
:param {{dataType}} {{paramName}}:{{#description}} {{{description}}}{{/description}}{{#required}} (required){{/required}}{{#optional}}(optional){{/optional}}
:param {{paramName}}:{{#description}} {{{description}}}{{/description}}{{#required}} (required){{/required}}{{#optional}}(optional){{/optional}}
:type {{paramName}}: {{dataType}}{{#optional}}, optional{{/optional}}
{{/allParams}}
:param async_req: Whether to execute the request asynchronously.
:type async_req: bool, optional
:param _preload_content: if False, the urllib3.HTTPResponse object will
be returned without reading/decoding response
data. Default is True.
:type _preload_content: bool, optional
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:return: {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}}
:return: Returns the result object.
If the method is called asynchronously,
returns the request thread.
:rtype: {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}}
"""
kwargs['_return_http_data_only'] = True
return self.{{operationId}}_with_http_info({{#sortParamsByRequiredFlag}}{{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{/sortParamsByRequiredFlag}}**kwargs) # noqa: E501
@@ -72,6 +77,7 @@ class {{classname}}(object):
{{/notes}}
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async_req=True
{{#sortParamsByRequiredFlag}}
>>> thread = api.{{operationId}}_with_http_info({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}async_req=True)
{{/sortParamsByRequiredFlag}}
@@ -80,22 +86,27 @@ class {{classname}}(object):
{{/sortParamsByRequiredFlag}}
>>> result = thread.get()
:param async_req bool: execute request asynchronously
{{#allParams}}
:param {{dataType}} {{paramName}}:{{#description}} {{{description}}}{{/description}}{{#required}} (required){{/required}}{{#optional}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/optional}}
:param {{paramName}}:{{#description}} {{{description}}}{{/description}}{{#required}} (required){{/required}}{{#optional}}(optional){{/optional}}
:type {{paramName}}: {{dataType}}{{#optional}}, optional{{/optional}}
{{/allParams}}
:param async_req: Whether to execute the request asynchronously.
:type async_req: bool, optional
:param _return_http_data_only: response data without head status code
and headers
:type _return_http_data_only: bool, optional
:param _preload_content: if False, the urllib3.HTTPResponse object will
be returned without reading/decoding response
data. Default is True.
:type _preload_content: bool, optional
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:return: {{#returnType}}tuple({{returnType}}, status_code(int), headers(HTTPHeaderDict)){{/returnType}}{{^returnType}}None{{/returnType}}
:return: Returns the result object.
If the method is called asynchronously,
returns the request thread.
:rtype: {{#returnType}}tuple({{returnType}}, status_code(int), headers(HTTPHeaderDict)){{/returnType}}{{^returnType}}None{{/returnType}}
"""
{{#servers.0}}

View File

@@ -107,7 +107,7 @@ class {{classname}}(object):
{{/description}}
:param {{name}}: The {{name}} of this {{classname}}. # noqa: E501
:type: {{dataType}}
:type {{name}}: {{dataType}}
"""
{{^isNullable}}
{{#required}}

View File

@@ -66,6 +66,7 @@ class {{classname}}(object):
{{/notes}}
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async_req=True
>>> thread = api.{{operationId}}({{#requiredParams}}{{^defaultValue}}{{paramName}}, {{/defaultValue}}{{/requiredParams}}{{#requiredParams}}{{#defaultValue}}{{paramName}}={{{defaultValue}}}, {{/defaultValue}}{{/requiredParams}}async_req=True)
>>> result = thread.get()

View File

@@ -291,6 +291,7 @@ class ApiClient(object):
({str: (bool, str, int, float, date, datetime, str, none_type)},)
:param _check_type: boolean, whether to check the types of the data
received from the server
:type _check_type: bool
:return: deserialized object.
"""
@@ -350,22 +351,28 @@ class ApiClient(object):
(float, none_type)
([int, none_type],)
({str: (bool, str, int, float, date, datetime, str, none_type)},)
:param files dict: key -> field name, value -> a list of open file
:param files: key -> field name, value -> a list of open file
objects for `multipart/form-data`.
:type files: dict
:param async_req bool: execute request asynchronously
:type async_req: bool, optional
:param _return_http_data_only: response data without head status code
and headers
:type _return_http_data_only: bool, optional
:param collection_formats: dict of collection formats for path, query,
header, and post parameters.
:type collection_formats: dict, optional
:param _preload_content: if False, the urllib3.HTTPResponse object will
be returned without reading/decoding response
data. Default is True.
:type _preload_content: bool, optional
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:param _check_type: boolean describing if the data back from the server
should have its type checked.
:type _check_type: bool, optional
:return:
If async_req parameter is True,
the request will be called asynchronously.
@@ -559,9 +566,9 @@ class ApiClient(object):
:param headers: Header parameters dict to be updated.
:param querys: Query parameters tuple list to be updated.
:param auth_settings: Authentication setting identifiers list.
:resource_path: A string representation of the HTTP request resource path.
:method: A string representation of the HTTP request method.
:body: A object representing the body of the HTTP request.
:param resource_path: A string representation of the HTTP request resource path.
:param method: A string representation of the HTTP request method.
:param body: A object representing the body of the HTTP request.
The object type is the return value of sanitize_for_serialization().
"""
if not auth_settings:

View File

@@ -37,7 +37,12 @@ from {{packageName}}.model_utils import ( # noqa: F401
{{> python-experimental/model_templates/model_simple }}
{{/isAlias}}
{{^isAlias}}
{{#isArrayModel}}
{{> python-experimental/model_templates/model_simple }}
{{/isArrayModel}}
{{^isArrayModel}}
{{> python-experimental/model_templates/model_normal }}
{{/isArrayModel}}
{{/isAlias}}
{{/interfaces}}
{{#interfaces}}

View File

@@ -41,7 +41,7 @@ export class {{classname}} extends BaseAPI {
{{#hasParams}}
{{#allParams}}
{{#required}}
throwIfNullOrUndefined({{> paramNamePartial}}, '{{nickname}}');
throwIfNullOrUndefined({{> paramNamePartial}}, '{{> paramNamePartial}}', '{{nickname}}');
{{/required}}
{{/allParams}}

View File

@@ -178,9 +178,9 @@ export const throwIfRequired = (params: {[key: string]: any}, key: string, nickn
}
};
export const throwIfNullOrUndefined = (value: any, nickname?: string) => {
export const throwIfNullOrUndefined = (value: any, paramName: string, nickname: string) => {
if (value == null) {
throw new Error(`Parameter "${value}" was null or undefined when calling "${nickname}".`);
throw new Error(`Parameter "${paramName}" was null or undefined when calling "${nickname}".`);
}
};

View File

@@ -1,30 +0,0 @@
## {{npmName}}@{{npmVersion}}
This generator creates TypeScript/JavaScript client that utilizes {{framework}}.
### Building
To build and compile the typescript sources to javascript use:
```
npm install
npm run build
```
### Publishing
First build the package then run ```npm publish```
### Consuming
navigate to the folder of your consuming project and run one of the following commands.
_published:_
```
npm install {{npmName}}@{{npmVersion}} --save
```
_unPublished (not recommended):_
```
npm install PATH_TO_GENERATED_PACKAGE --save

View File

@@ -1,212 +0,0 @@
// TODO: better import syntax?
import { BaseAPIRequestFactory, RequiredError } from './baseapi';
import {Configuration} from '../configuration';
import { RequestContext, HttpMethod, ResponseContext, HttpFile} from '../http/http';
{{#platforms}}
{{#node}}
import * as FormData from "form-data";
{{/node}}
{{/platforms}}
import {ObjectSerializer} from '../models/ObjectSerializer';
import {ApiException} from './exception';
import {isCodeInRange} from '../util';
{{#imports}}
import { {{classname}} } from '..{{filename}}';
{{/imports}}
{{#operations}}
/**
* {{#description}}{{{description}}}{{/description}}{{^description}}no description{{/description}}
*/
export class {{classname}}RequestFactory extends BaseAPIRequestFactory {
{{#operation}}
/**
{{#notes}}
* {{&notes}}
{{/notes}}
{{#summary}}
* {{&summary}}
{{/summary}}
{{#allParams}}
* @param {{paramName}} {{description}}
{{/allParams}}
*/
public async {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}options?: Configuration): Promise<RequestContext> {
let config = options || this.configuration;
{{#allParams}}
{{#required}}
// verify required parameter '{{paramName}}' is not null or undefined
if ({{paramName}} === null || {{paramName}} === undefined) {
throw new RequiredError('Required parameter {{paramName}} was null or undefined when calling {{nickname}}.');
}
{{/required}}
{{/allParams}}
// Path Params
const localVarPath = '{{{path}}}'{{#pathParams}}
.replace('{' + '{{baseName}}' + '}', encodeURIComponent(String({{paramName}}))){{/pathParams}};
// Make Request Context
const requestContext = config.baseServer.makeRequestContext(localVarPath, HttpMethod.{{httpMethod}});
requestContext.setHeaderParam("Accept", "application/json, */*;q=0.8")
// Query Params
{{#queryParams}}
if ({{paramName}} !== undefined) {
requestContext.setQueryParam("{{baseName}}", ObjectSerializer.serialize({{paramName}}, "{{{dataType}}}", "{{dataFormat}}"));
}
{{/queryParams}}
// Header Params
{{#headerParams}}
requestContext.setHeaderParam("{{baseName}}", ObjectSerializer.serialize({{paramName}}, "{{{dataType}}}", "{{dataFormat}}"));
{{/headerParams}}
// Form Params
{{#hasFormParams}}
let localVarFormParams = new FormData();
{{/hasFormParams}}
{{#formParams}}
{{#isListContainer}}
if ({{paramName}}) {
{{#isCollectionFormatMulti}}
{{paramName}}.forEach((element) => {
localVarFormParams.append('{{baseName}}', element as any);
})
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
// TODO: replace .append with .set
localVarFormParams.append('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS["{{collectionFormat}}"]));
{{/isCollectionFormatMulti}}
}
{{/isListContainer}}
{{^isListContainer}}
if ({{paramName}} !== undefined) {
// TODO: replace .append with .set
{{^isFile}}
localVarFormParams.append('{{baseName}}', {{paramName}} as any);
{{/isFile}}
{{#isFile}}
{{#platforms}}
{{#node}}
localVarFormParams.append('{{baseName}}', {{paramName}}.data, {{paramName}}.name);
{{/node}}
{{#browser}}
localVarFormParams.append('{{baseName}}', {{paramName}}, {{paramName}}.name);
{{/browser}}
{{/platforms}}
{{/isFile}}
}
{{/isListContainer}}
{{/formParams}}
{{#hasFormParams}}
requestContext.setBody(localVarFormParams);
{{/hasFormParams}}
// Body Params
{{#bodyParam}}
const contentType = ObjectSerializer.getPreferredMediaType([{{#consumes}}
"{{{mediaType}}}"{{#hasMore}},{{/hasMore}}
{{/consumes}}]);
requestContext.setHeaderParam("Content-Type", contentType);
const serializedBody = ObjectSerializer.stringify(
ObjectSerializer.serialize({{paramName}}, "{{{dataType}}}", "{{dataFormat}}"),
contentType
);
requestContext.setBody(serializedBody);
{{/bodyParam}}
{{#hasAuthMethods}}
let authMethod = null;
{{/hasAuthMethods}}
// Apply auth methods
{{#authMethods}}
authMethod = config.authMethods["{{name}}"]
if (authMethod) {
await authMethod.applySecurityAuthentication(requestContext);
}
{{/authMethods}}
return requestContext;
}
{{/operation}}
}
{{/operations}}
{{#operations}}
export class {{classname}}ResponseProcessor {
{{#operation}}
/**
* Unwraps the actual response sent by the server from the response context and deserializes the response content
* to the expected objects
*
* @params response Response returned by the server for a request to {{nickname}}
* @throws ApiException if the response code was not in [200, 299]
*/
public async {{nickname}}(response: ResponseContext): Promise<{{#returnType}}{{{returnType}}}{{/returnType}} {{^returnType}}void{{/returnType}}> {
const contentType = ObjectSerializer.normalizeMediaType(response.headers["content-type"]);
{{#responses}}
if (isCodeInRange("{{code}}", response.httpStatusCode)) {
{{#dataType}}
{{#isBinary}}
const body: {{{dataType}}} = await response.getBodyAsFile() as any as {{{returnType}}};
{{/isBinary}}
{{^isBinary}}
const body: {{{dataType}}} = ObjectSerializer.deserialize(
ObjectSerializer.parse(await response.body.text(), contentType),
"{{{dataType}}}", "{{returnFormat}}"
) as {{{dataType}}};
{{/isBinary}}
{{#is2xx}}
return body;
{{/is2xx}}
{{^is2xx}}
throw new ApiException<{{{dataType}}}>({{code}}, body);
{{/is2xx}}
{{/dataType}}
{{^dataType}}
{{#is2xx}}
return;
{{/is2xx}}
{{^is2xx}}
throw new ApiException<string>(response.httpStatusCode, "{{message}}");
{{/is2xx}}
{{/dataType}}
}
{{/responses}}
// Work around for missing responses in specification, e.g. for petstore.yaml
if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) {
{{#returnType}}
{{#isBinary}}
const body: {{{returnType}}} = await response.getBodyAsFile() as any as {{{returnType}}};
{{/isBinary}}
{{^isBinary}}
const body: {{{returnType}}} = ObjectSerializer.deserialize(
ObjectSerializer.parse(await response.body.text(), contentType),
"{{{returnType}}}", "{{returnFormat}}"
) as {{{returnType}}};
{{/isBinary}}
return body;
{{/returnType}}
{{^returnType}}
return;
{{/returnType}}
}
let body = response.body || "";
throw new ApiException<string>(response.httpStatusCode, "Unknown API Status Code!\nBody: \"" + body + "\"");
}
{{/operation}}
}
{{/operations}}

View File

@@ -1,37 +0,0 @@
import { Configuration } from '../configuration'
/**
*
* @export
*/
export const COLLECTION_FORMATS = {
csv: ",",
ssv: " ",
tsv: "\t",
pipes: "|",
};
/**
*
* @export
* @class BaseAPI
*/
export class BaseAPIRequestFactory {
constructor(protected configuration: Configuration) {
}
};
/**
*
* @export
* @class RequiredError
* @extends {Error}
*/
export class RequiredError extends Error {
name: "RequiredError" = "RequiredError";
constructor(public field: string, msg?: string) {
super(msg);
}
}

View File

@@ -1,14 +0,0 @@
/**
* Represents an error caused by an api call i.e. it has attributes for a HTTP status code
* and the returned body object.
*
* Example
* API returns a ErrorMessageObject whenever HTTP status code is not in [200, 299]
* => ApiException(404, someErrorMessageObject)
*
*/
export class ApiException<T> extends Error {
public constructor(public code: number, public body: T) {
super("HTTP-Code: " + code + "\nMessage: " + JSON.stringify(body))
}
}

View File

@@ -1,66 +0,0 @@
import {RequestContext, ResponseContext} from './http/http';
import { Observable, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'./rxjsStub'{{/useRxJS}};
/**
* Defines the contract for a middleware intercepting requests before
* they are sent (but after the RequestContext was created)
* and before the ResponseContext is unwrapped.
*
*/
export interface Middleware {
/**
* Modifies the request before the request is sent.
*
* @param context RequestContext of a request which is about to be sent to the server
* @returns an observable of the updated request context
*
*/
pre(context: RequestContext): Observable<RequestContext>;
/**
* Modifies the returned response before it is deserialized.
*
* @param context ResponseContext of a sent request
* @returns an observable of the modified response context
*/
post(context: ResponseContext): Observable<ResponseContext>;
}
export class PromiseMiddlewareWrapper implements Middleware {
public constructor(private middleware: PromiseMiddleware) {
}
pre(context: RequestContext): Observable<RequestContext> {
return from(this.middleware.pre(context));
}
post(context: ResponseContext): Observable<ResponseContext> {
return from(this.middleware.post(context));
}
}
/**
* Defines the contract for a middleware intercepting requests before
* they are sent (but after the RequestContext was created)
* and before the ResponseContext is unwrapped.
*
*/
export interface PromiseMiddleware {
/**
* Modifies the request before the request is sent.
*
* @param context RequestContext of a request which is about to be sent to the server
* @returns an observable of the updated request context
*
*/
pre(context: RequestContext): Promise<RequestContext>;
/**
* Modifies the returned response before it is deserialized.
*
* @param context ResponseContext of a sent request
* @returns an observable of the modified response context
*/
post(context: ResponseContext): Promise<ResponseContext>;
}

View File

@@ -1,168 +0,0 @@
import {RequestContext} from '../http/http';
// typings for btoa are incorrect
{{#platforms}}
{{#node}}
//@ts-ignore
import * as btoa from "btoa";
{{/node}}
{{/platforms}}
/**
* Base class for all authentication schemes.
*
*/
export abstract class SecurityAuthentication {
public constructor(private name: string) {
}
/*
*
* @return returns the name of the security authentication as specified in OAI
*/
public getName(): string {
return this.name;
}
/**
* Applies the authentication scheme to the request context
*
* @params context the request context which should use this authentication scheme
*/
public abstract applySecurityAuthentication(context: RequestContext): void | Promise<void>;
}
/**
* Applies an api key to the request context.
*
*/
export class APIKeyAuthentication extends SecurityAuthentication {
/**
* Configures this api key authentication with the necessary properties
*
* @param authName: name of this authentication scheme as specified in the swagger.json
* @param paramName: Parameter name used for the api key
* @param keyLocation: Parameter location, either query, header or cookie.
* @param apiKey: The api key to be used for every request
*/
public constructor(authName: string, private paramName: string, private keyLocation: "query" | "header" | "cookie", private apiKey: string) {
super(authName);
}
public applySecurityAuthentication(context: RequestContext) {
if (this.keyLocation === "header") {
context.setHeaderParam(this.paramName, this.apiKey);
} else if (this.keyLocation === "cookie") {
context.addCookie(this.paramName, this.apiKey);
} else if (this.keyLocation === "query") {
context.setQueryParam(this.paramName, this.apiKey);
}
}
}
/**
* Applies basic http authentication to a request.
*
*/
export class HttpBasicAuthentication extends SecurityAuthentication {
/**
* Configures the http authentication with the required details.
*
*
* @param authName name of the authentication scheme as defined in swagger json
* @param username username for http basic authentication
* @param password password for http basic authentication
*/
public constructor(authName: string, private username: string, private password: string) {
super(authName);
}
public applySecurityAuthentication(context: RequestContext) {
let comb = this.username + ":" + this.password;
context.setHeaderParam("Authorization", "Basic " + btoa(comb));
}
}
export interface TokenProvider {
getToken(): Promise<string> | string;
}
/**
* Applies http bearer authentication to a request.
*
*/
export class HttpBearerAuthentication extends SecurityAuthentication {
/**
* Configures the http authentication with the required details.
*
*
* @param authName name of the authentication scheme as defined in openapi specification
* @param tokenProvider service that can provide the up-to-date token when needed
*/
public constructor(authName: string, private tokenProvider: TokenProvider) {
super(authName);
}
public async applySecurityAuthentication(context: RequestContext) {
context.setHeaderParam("Authorization", "Bearer " + await this.tokenProvider.getToken());
}
}
// TODO: How to handle oauth2 authentication!
export class OAuth2Authentication extends SecurityAuthentication {
public constructor(authName: string) {
super(authName);
}
public applySecurityAuthentication(context: RequestContext) {
// TODO
}
}
export type AuthMethods = {
{{#authMethods}}
"{{name}}"?: {{#isApiKey}}APIKeyAuthentication{{/isApiKey}}{{#isBasicBasic}}HttpBasicAuthentication{{/isBasicBasic}}{{#isBasicBearer}}HttpBearerAuthentication{{/isBasicBearer}}{{#isOAuth}}OAuth2Authentication{{/isOAuth}},
{{/authMethods}}
}
export type ApiKeyConfiguration = string;
export type HttpBasicConfiguration = { "username": string, "password": string };
export type HttpBearerConfiguration = { tokenProvider: TokenProvider };
export type OAuth2Configuration = string;
export type AuthMethodsConfiguration = { {{#authMethods}}"{{name}}"?:{{#isApiKey}}ApiKeyConfiguration{{/isApiKey}}{{#isBasicBasic}}HttpBasicConfiguration{{/isBasicBasic}}{{#isBasicBearer}}HttpBearerConfiguration{{/isBasicBearer}}{{#isOAuth}}OAuth2Configuration{{/isOAuth}}, {{/authMethods}} }
/**
* Creates the authentication methods from a swagger description.
*
*/
export function configureAuthMethods(config: AuthMethodsConfiguration | undefined): AuthMethods {
let authMethods: AuthMethods = {}
if (!config) {
return authMethods;
}
{{#authMethods}}
if (config["{{name}}"]) {
{{#isApiKey}}
authMethods["{{name}}"] = new APIKeyAuthentication("{{name}}", "{{keyParamName}}", {{#isKeyInQuery}}"query"{{/isKeyInQuery}}{{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{#isKeyInCookie}}"cookie"{{/isKeyInCookie}}, <string> config["{{name}}"]);
{{/isApiKey}}
{{#isBasicBasic}}
authMethods["{{name}}"] = new HttpBasicAuthentication("{{name}}", config["{{name}}"]["username"], config["{{name}}"]["password"]);
{{/isBasicBasic}}
{{#isBasicBearer}}
authMethods["{{name}}"] = new HttpBearerAuthentication("{{name}}", config["{{name}}"]["tokenProvider"]);
{{/isBasicBearer}}
{{#isOAuth}}
authMethods["{{name}}"] = new OAuth2Authentication("{{name}}");
{{/isOAuth}}
}
{{/authMethods}}
return authMethods;
}

View File

@@ -1,67 +0,0 @@
import {HttpLibrary} from './http/http';
import {Middleware, PromiseMiddleware, PromiseMiddlewareWrapper} from './middleware';
{{#frameworks}}
{{#fetch-api}}
import {IsomorphicFetchHttpLibrary} from "./http/isomorphic-fetch";
{{/fetch-api}}
{{#jquery}}
import {JQueryHttpLibrary} from "./http/jquery";
{{/jquery}}
{{/frameworks}}
import {ServerConfiguration, server1} from './servers';
import {configureAuthMethods, AuthMethods, AuthMethodsConfiguration} from './auth/auth';
/**
* Inetrface with which a configuration object can be configured.
*
*/
export interface ConfigurationParameters {
/**
* Default server to use
*/
baseServer?: ServerConfiguration<any>;
/**
* HTTP library to use e.g. IsomorphicFetch
*/
httpApi?: HttpLibrary;
/**
* The middlewares which will be applied to requests and responses
*/
middleware?: Middleware[]; // middleware to apply before/after fetch requests
/**
* configures all middlewares using the promise api instead of observables (which Middleware uses)
*/
promiseMiddleware?: PromiseMiddleware[];
/**
* Configuration for the available authentication methods
*/
authMethods?: AuthMethodsConfiguration
}
export class Configuration {
baseServer: ServerConfiguration<any>;
httpApi: HttpLibrary;
middleware: Middleware[];
authMethods: AuthMethods;
/**
* Creates a new configuration object based on the given configuration.
* If a property is not included in conf, a default is used:
* - baseServer: server1
* - httpApi: IsomorphicFetchHttpLibrary
* - middleware: []
* - promiseMiddleware: []
* - authMethods: {}
* @param conf particial configuration
*/
constructor(conf: ConfigurationParameters = {}) {
this.baseServer = conf.baseServer !== undefined ? conf.baseServer : server1;
this.httpApi = conf.httpApi || {{#frameworks}}{{#fetch-api}}new IsomorphicFetchHttpLibrary(){{/fetch-api}}{{#jquery}}new JQueryHttpLibrary{{/jquery}}{{/frameworks}}; // TODO: replace with window.fetch if available?
this.middleware = conf.middleware || [];
this.authMethods = configureAuthMethods(conf.authMethods);
if (conf.promiseMiddleware) {
conf.promiseMiddleware.forEach(m => this.middleware.push(new PromiseMiddlewareWrapper(m)));
}
}
}

View File

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

View File

@@ -1,246 +0,0 @@
{{#platforms}}
{{#node}}
// TODO: evaluate if we can easily get rid of this library
import * as FormData from "form-data";
{{/node}}
{{/platforms}}
// typings of url-parse are incorrect...
// @ts-ignore
import * as URLParse from "url-parse";
import { Observable } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub'{{/useRxJS}};
{{#frameworks}}
{{#fetch-api}}
export * from './isomorphic-fetch';
{{/fetch-api}}
{{#jquery}}
export * from './jquery';
{{/jquery}}
{{/frameworks}}
/**
* Represents an HTTP method.
*/
export enum HttpMethod {
GET = "GET",
HEAD = "HEAD",
POST = "POST",
PUT = "PUT",
DELETE = "DELETE",
CONNECT = "CONNECT",
OPTIONS = "OPTIONS",
TRACE = "TRACE",
PATCH = "PATCH"
}
/**
* Represents an HTTP file which will be transferred from or to a server.
*/
{{#platforms}}
{{#node}}
export type HttpFile = {
data: {{{fileContentDataType}}},
name: string
};
{{/node}}
{{#browser}}
export type HttpFile = {{{fileContentDataType}}} & { readonly name: string };
{{/browser}}
{{/platforms}}
export class HttpException extends Error {
public constructor(msg: string) {
super(msg);
}
}
/**
* Represents the body of an outgoing HTTP request.
*/
export type RequestBody = undefined | string | FormData;
/**
* Represents an HTTP request context
*/
export class RequestContext {
private headers: { [key: string]: string } = {};
private body: RequestBody = undefined;
private url: URLParse;
/**
* Creates the request context using a http method and request resource url
*
* @param url url of the requested resource
* @param httpMethod http method
*/
public constructor(url: string, private httpMethod: HttpMethod) {
this.url = URLParse(url, true);
}
/*
* Returns the url set in the constructor including the query string
*
*/
public getUrl(): string {
return this.url.toString();
}
/**
* Replaces the url set in the constructor with this url.
*
*/
public setUrl(url: string) {
this.url = URLParse(url, true);
}
/**
* Sets the body of the http request either as a string or FormData
*
* Note that setting a body on a HTTP GET, HEAD, DELETE, CONNECT or TRACE
* request is discouraged.
* https://httpwg.org/http-core/draft-ietf-httpbis-semantics-latest.html#rfc.section.7.3.1
*
* @param body the body of the request
*/
public setBody(body: RequestBody) {
this.body = body;
}
public getHttpMethod(): HttpMethod {
return this.httpMethod;
}
public getHeaders(): { [key: string]: string } {
return this.headers;
}
public getBody(): RequestBody {
return this.body;
}
public setQueryParam(name: string, value: string) {
let queryObj = this.url.query;
queryObj[name] = value;
this.url.set("query", queryObj);
}
/**
* Sets a cookie with the name and value. NO check for duplicate cookies is performed
*
*/
public addCookie(name: string, value: string): void {
if (!this.headers["Cookie"]) {
this.headers["Cookie"] = "";
}
this.headers["Cookie"] += name + "=" + value + "; ";
}
public setHeaderParam(key: string, value: string): void {
this.headers[key] = value;
}
}
export interface ResponseBody {
text(): Promise<string>;
binary(): Promise<{{{fileContentDataType}}}>;
}
/**
* Helper class to generate a `ResponseBody` from binary data
*/
export class SelfDecodingBody implements ResponseBody {
constructor(private dataSource: Promise<{{{fileContentDataType}}}>) {}
binary(): Promise<{{{fileContentDataType}}}> {
return this.dataSource;
}
async text(): Promise<string> {
const data: {{{fileContentDataType}}} = await this.dataSource;
{{#platforms}}
{{#node}}
return data.toString();
{{/node}}
{{#browser}}
// @ts-ignore
if (data.text) {
// @ts-ignore
return data.text();
}
return new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener("load", () => resolve(reader.result as string));
reader.addEventListener("error", () => reject(reader.error));
reader.readAsText(data);
});
{{/browser}}
{{/platforms}}
}
}
export class ResponseContext {
public constructor(
public httpStatusCode: number,
public headers: { [key: string]: string },
public body: ResponseBody
) {}
/**
* Parse header value in the form `value; param1="value1"`
*
* E.g. for Content-Type or Content-Disposition
* Parameter names are converted to lower case
* The first parameter is returned with the key `""`
*/
public getParsedHeader(headerName: string): { [parameter: string]: string } {
const result: { [parameter: string]: string } = {};
if (!this.headers[headerName]) {
return result;
}
const parameters = this.headers[headerName].split(";");
for (const parameter of parameters) {
let [key, value] = parameter.split("=", 2);
key = key.toLowerCase().trim();
if (value === undefined) {
result[""] = key;
} else {
value = value.trim();
if (value.startsWith('"') && value.endsWith('"')) {
value = value.substring(1, value.length - 1);
}
result[key] = value;
}
}
return result;
}
public async getBodyAsFile(): Promise<HttpFile> {
const data = await this.body.binary();
const fileName = this.getParsedHeader("content-disposition")["filename"] || "";
{{#platforms}}
{{#node}}
return { data, name: fileName };
{{/node}}
{{#browser}}
const contentType = this.headers["content-type"] || "";
try {
return new File([data], fileName, { type: contentType });
} catch (error) {
/** Fallback for when the File constructor is not available */
return Object.assign(data, {
name: fileName,
type: contentType
});
}
{{/browser}}
{{/platforms}}
}
}
export interface HttpLibrary {
send(request: RequestContext): Observable<ResponseContext>;
}

View File

@@ -1,53 +0,0 @@
import {HttpLibrary, RequestContext, ResponseContext} from './http';
import { from, Observable } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub'{{/useRxJS}};
{{#platforms}}
{{#node}}
import fetch from "node-fetch";
{{/node}}
{{#browser}}
import "whatwg-fetch";
{{/browser}}
{{/platforms}}
export class IsomorphicFetchHttpLibrary implements HttpLibrary {
public send(request: RequestContext): Observable<ResponseContext> {
let method = request.getHttpMethod().toString();
let body = request.getBody();
const resultPromise = fetch(request.getUrl(), {
method: method,
body: body as any,
headers: request.getHeaders(),
{{#platforms}}
{{#browser}}
credentials: "same-origin"
{{/browser}}
{{/platforms}}
}).then((resp: any) => {
const headers: { [name: string]: string } = {};
resp.headers.forEach((value: string, name: string) => {
headers[name] = value;
});
{{#platforms}}
{{#node}}
const body = {
text: () => resp.text(),
binary: () => resp.buffer()
};
{{/node}}
{{^node}}
const body = {
text: () => resp.text(),
binary: () => resp.blob()
};
{{/node}}
{{/platforms}}
return new ResponseContext(resp.status, headers, body);
});
return from<Promise<ResponseContext>>(resultPromise);
}
}

View File

@@ -1,87 +0,0 @@
import { HttpLibrary, RequestContext, ResponseContext, HttpException, SelfDecodingBody } from './http';
import * as e6p from 'es6-promise'
import { from, Observable } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub'{{/useRxJS}};
e6p.polyfill();
import * as $ from 'jquery';
export class JQueryHttpLibrary implements HttpLibrary {
public send(request: RequestContext): Observable<ResponseContext> {
let method = request.getHttpMethod().toString();
let body = request.getBody();
let headerParams = request.getHeaders()
let requestOptions: any = {
url: request.getUrl(),
type: method,
headers: request.getHeaders(),
processData: false,
xhrFields: { withCredentials: true },
data: body
};
// If we want a blob, we have to set the xhrFields' responseType AND add a
// custom converter to overwrite the default deserialization of JQuery...
requestOptions["xhrFields"] = { responseType: 'blob' };
requestOptions["converters"] = {}
requestOptions["converters"]["* blob"] = (result:any) => result;
requestOptions["dataType"] = "blob";
if (request.getHeaders()['Content-Type']) {
requestOptions.contentType = headerParams['Content-Type'];
}
requestOptions.dataFilter = ((headerParams: { [key:string]: string}) => {
return (data: string, type: string) => {
if (headerParams["Accept"] == "application/json" && data == "") {
return "{}"
} else {
return data
}
}
})(headerParams);
if (request.getHeaders()["Cookie"]) {
throw new HttpException("Setting the \"Cookie\"-Header field is blocked by every major browser when using jquery.ajax requests. Please switch to another library like fetch to enable this option");
}
if (body && body.constructor.name == "FormData") {
requestOptions.contentType = false;
}
const sentRequest = $.ajax(requestOptions);
const resultPromise = new Promise<ResponseContext>((resolve, reject) => {
sentRequest.done((data, _, jqXHR) => {
const result = new ResponseContext(
jqXHR.status,
this.getResponseHeaders(jqXHR),
new SelfDecodingBody(Promise.resolve(data))
);
resolve(result);
})
sentRequest.fail((jqXHR: any) => {
const headers = this.getResponseHeaders(jqXHR)
const result = new ResponseContext(jqXHR.status, headers, jqXHR.responseText);
resolve(result);
})
})
return from(resultPromise);
}
private getResponseHeaders(jqXHR: any): { [key: string]: string } {
const responseHeaders: { [key: string]: string } = {};
var headers = jqXHR.getAllResponseHeaders();
headers = headers.split("\n");
headers.forEach(function (header: any) {
header = header.split(": ");
var key = header.shift();
if (key.length == 0) return
// chrome60+ force lowercase, other browsers can be different
key = key.toLowerCase();
responseHeaders[key] = header.join(": ");
});
return responseHeaders
}
}

View File

@@ -1,49 +0,0 @@
import {RequestContext, HttpMethod} from './http/http';
/**
*
* Represents the configuration of a server including its
* url template and variable configuration based on the url.
*
*/
export class ServerConfiguration<T extends { [key: string]: string }> {
public constructor(private url: string, private variableConfiguration: T) {}
/**
* Sets the value of the variables of this server.
*
* @param variableConfiguration a partial variable configuration for the variables contained in the url
*/
public setVariables(variableConfiguration: Partial<T>) {
Object.assign(this.variableConfiguration, variableConfiguration);
}
public getConfiguration(): T {
return this.variableConfiguration
}
private getUrl() {
let replacedUrl = this.url;
for (const key in this.variableConfiguration) {
var re = new RegExp("{" + key + "}","g");
replacedUrl = replacedUrl.replace(re, this.variableConfiguration[key]);
}
return replacedUrl
}
/**
* Creates a new request context for this server using the url with variables
* replaced with their respective values and the endpoint of the request appended.
*
* @param endpoint the endpoint to be queried on the server
* @param httpMethod httpMethod to be used
*
*/
public makeRequestContext(endpoint: string, httpMethod: HttpMethod): RequestContext {
return new RequestContext(this.getUrl() + endpoint, httpMethod);
}
}
{{#servers}}
export const server{{-index}} = new ServerConfiguration<{ {{#variables}} "{{name}}": {{#enumValues}}"{{.}}"{{^-last}} | {{/-last}}{{/enumValues}}{{^enumValues}}string{{/enumValues}}{{^-last}},{{/-last}} {{/variables}} }>("{{url}}", { {{#variables}} "{{name}}": "{{defaultValue}}" {{^-last}},{{/-last}}{{/variables}} })
{{/servers}}

View File

@@ -1,26 +0,0 @@
import 'es6-promise/auto';
export * from './http/http';
export * from './auth/auth';
export * from './models/all';
export { Configuration} from './configuration'
export * from './apis/exception';
export * from './servers';
{{#useRxJS}}
export { Middleware } from './middleware';
{{/useRxJS}}
{{^useRxJS}}
export { PromiseMiddleware as Middleware } from './middleware';
{{/useRxJS}}
{{#useObjectParameters}}
export { {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{classname}}{{operationIdCamelCase}}Request, {{/operation}}Object{{classname}} as {{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './types/ObjectParamAPI';
{{/useObjectParameters}}
{{^useObjectParameters}}
{{#useRxJS}}
export { {{#apiInfo}}{{#apis}}{{#operations}}Observable{{classname}} as {{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './types/ObservableAPI';
{{/useRxJS}}
{{^useRxJS}}
export { {{#apiInfo}}{{#apis}}{{#operations}}Promise{{classname}} as {{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './types/PromiseAPI';
{{/useRxJS}}
{{/useObjectParameters}}

View File

@@ -1,11 +0,0 @@
/**
* {{{appName}}}
* {{{appDescription}}}
*
* {{#version}}OpenAPI spec version: {{{version}}}{{/version}}
* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@@ -1,240 +0,0 @@
{{#models}}
{{#model}}
export * from './{{{ classFilename }}}';
{{/model}}
{{/models}}
{{#models}}
{{#model}}
import { {{classname}}{{#hasEnums}}{{#vars}}{{#isEnum}}, {{classname}}{{enumName}} {{/isEnum}} {{/vars}}{{/hasEnums}} } from './{{{ classFilename }}}';
{{/model}}
{{/models}}
/* tslint:disable:no-unused-variable */
let primitives = [
"string",
"boolean",
"double",
"integer",
"long",
"float",
"number",
"any"
];
const supportedMediaTypes: { [mediaType: string]: number } = {
"application/json": Infinity,
"application/octet-stream": 0
}
let enumsMap: Set<string> = new Set<string>([
{{#models}}
{{#model}}
{{#hasEnums}}
{{#vars}}
{{#isEnum}}
"{{classname}}{{enumName}}",
{{/isEnum}}
{{/vars}}
{{/hasEnums}}
{{/model}}
{{/models}}
]);
let typeMap: {[index: string]: any} = {
{{#models}}
{{#model}}
"{{classname}}": {{classname}},
{{/model}}
{{/models}}
}
export class ObjectSerializer {
public static findCorrectType(data: any, expectedType: string) {
if (data == undefined) {
return expectedType;
} else if (primitives.indexOf(expectedType.toLowerCase()) !== -1) {
return expectedType;
} else if (expectedType === "Date") {
return expectedType;
} else {
if (enumsMap.has(expectedType)) {
return expectedType;
}
if (!typeMap[expectedType]) {
return expectedType; // w/e we don't know the type
}
// Check the discriminator
let discriminatorProperty = typeMap[expectedType].discriminator;
if (discriminatorProperty == null) {
return expectedType; // the type does not have a discriminator. use it.
} else {
if (data[discriminatorProperty]) {
var discriminatorType = data[discriminatorProperty];
if(typeMap[discriminatorType]){
return discriminatorType; // use the type given in the discriminator
} else {
return expectedType; // discriminator did not map to a type
}
} else {
return expectedType; // discriminator was not present (or an empty string)
}
}
}
}
public static serialize(data: any, type: string, format: string) {
if (data == undefined) {
return data;
} else if (primitives.indexOf(type.toLowerCase()) !== -1) {
return data;
} else if (type.lastIndexOf("Array<", 0) === 0) { // string.startsWith pre es6
let subType: string = type.replace("Array<", ""); // Array<Type> => Type>
subType = subType.substring(0, subType.length - 1); // Type> => Type
let transformedData: any[] = [];
for (let index in data) {
let date = data[index];
transformedData.push(ObjectSerializer.serialize(date, subType, format));
}
return transformedData;
} else if (type === "Date") {
if (format == "date") {
let month = data.getMonth()+1
month = month < 10 ? "0" + month.toString() : month.toString()
let day = data.getDate();
day = day < 10 ? "0" + day.toString() : day.toString();
return data.getFullYear() + "-" + month + "-" + day;
} else {
return data.toISOString();
}
} else {
if (enumsMap.has(type)) {
return data;
}
if (!typeMap[type]) { // in case we dont know the type
return data;
}
// Get the actual type of this object
type = this.findCorrectType(data, type);
// get the map for the correct type.
let attributeTypes = typeMap[type].getAttributeTypeMap();
let instance: {[index: string]: any} = {};
for (let index in attributeTypes) {
let attributeType = attributeTypes[index];
instance[attributeType.baseName] = ObjectSerializer.serialize(data[attributeType.name], attributeType.type, attributeType.format);
}
return instance;
}
}
public static deserialize(data: any, type: string, format: string) {
// polymorphism may change the actual type.
type = ObjectSerializer.findCorrectType(data, type);
if (data == undefined) {
return data;
} else if (primitives.indexOf(type.toLowerCase()) !== -1) {
return data;
} else if (type.lastIndexOf("Array<", 0) === 0) { // string.startsWith pre es6
let subType: string = type.replace("Array<", ""); // Array<Type> => Type>
subType = subType.substring(0, subType.length - 1); // Type> => Type
let transformedData: any[] = [];
for (let index in data) {
let date = data[index];
transformedData.push(ObjectSerializer.deserialize(date, subType, format));
}
return transformedData;
} else if (type === "Date") {
return new Date(data);
} else {
if (enumsMap.has(type)) {// is Enum
return data;
}
if (!typeMap[type]) { // dont know the type
return data;
}
let instance = new typeMap[type]();
let attributeTypes = typeMap[type].getAttributeTypeMap();
for (let index in attributeTypes) {
let attributeType = attributeTypes[index];
instance[attributeType.name] = ObjectSerializer.deserialize(data[attributeType.baseName], attributeType.type, attributeType.format);
}
return instance;
}
}
/**
* Normalize media type
*
* We currently do not handle any media types attributes, i.e. anything
* after a semicolon. All content is assumed to be UTF-8 compatible.
*/
public static normalizeMediaType(mediaType: string | undefined): string | undefined {
if (mediaType === undefined) {
return undefined;
}
return mediaType.split(";")[0].trim().toLowerCase();
}
/**
* From a list of possible media types, choose the one we can handle best.
*
* The order of the given media types does not have any impact on the choice
* made.
*/
public static getPreferredMediaType(mediaTypes: Array<string>): string {
/** According to OAS 3 we should default to json */
if (!mediaTypes) {
return "application/json";
}
const normalMediaTypes = mediaTypes.map(this.normalizeMediaType);
let selectedMediaType: string | undefined = undefined;
let selectedRank: number = -Infinity;
for (const mediaType of normalMediaTypes) {
if (supportedMediaTypes[mediaType!] > selectedRank) {
selectedMediaType = mediaType;
selectedRank = supportedMediaTypes[mediaType!];
}
}
if (selectedMediaType === undefined) {
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
}
return selectedMediaType!;
}
/**
* Convert data to a string according the given media type
*/
public static stringify(data: any, mediaType: string): string {
if (mediaType === "application/json") {
return JSON.stringify(data);
}
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.stringify.");
}
/**
* Parse data from a string according to the given media type
*/
public static parse(rawData: string, mediaType: string | undefined) {
if (mediaType === undefined) {
throw new Error("Cannot parse content. No Content-Type defined.");
}
if (mediaType === "application/json") {
return JSON.parse(rawData);
}
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse.");
}
}

View File

@@ -1,79 +0,0 @@
{{>licenseInfo}}
{{#models}}
{{#model}}
{{#tsImports}}
import { {{classname}} } from './{{filename}}';
{{/tsImports}}
import { HttpFile } from '../http/http';
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
export class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
{{#vars}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
'{{name}}'{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}};
{{/vars}}
{{#discriminator}}
static readonly discriminator: string | undefined = "{{discriminatorName}}";
{{/discriminator}}
{{^discriminator}}
static readonly discriminator: string | undefined = undefined;
{{/discriminator}}
{{^isArrayModel}}
static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [
{{#vars}}
{
"name": "{{name}}",
"baseName": "{{baseName}}",
"type": "{{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}",
"format": "{{dataFormat}}"
}{{#hasMore}},
{{/hasMore}}
{{/vars}}
];
static getAttributeTypeMap() {
{{#parent}}
return super.getAttributeTypeMap().concat({{classname}}.attributeTypeMap);
{{/parent}}
{{^parent}}
return {{classname}}.attributeTypeMap;
{{/parent}}
}
{{/isArrayModel}}
public constructor() {
{{#parent}}
super();
{{/parent}}
{{#allVars}}
{{#discriminatorValue}}
this.{{name}} = "{{discriminatorValue}}";
{{/discriminatorValue}}
{{/allVars}}
{{#discriminatorName}}
this.{{discriminatorName}} = "{{classname}}";
{{/discriminatorName}}
}
}
{{#hasEnums}}
{{#vars}}
{{#isEnum}}
export type {{classname}}{{enumName}} ={{#allowableValues}}{{#values}} "{{.}}" {{^-last}}|{{/-last}}{{/values}}{{/allowableValues}};
{{/isEnum}}
{{/vars}}
{{/hasEnums}}
{{/model}}
{{/models}}

View File

@@ -1,5 +0,0 @@
{{#models}}
{{#model}}
export * from './{{{ classFilename }}}'
{{/model}}
{{/models}}

View File

@@ -1,58 +0,0 @@
{
"name": "{{npmName}}",
"version": "{{npmVersion}}",
"description": "OpenAPI client for {{npmName}}",
"author": "OpenAPI-Generator Contributors",
"keywords": [
"fetch",
"typescript",
"openapi-client",
"openapi-generator"
],
"license": "Unlicense",
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",
"scripts": {
"build": "tsc",
"prepublishOnly": "npm run build"
},
"dependencies": {
{{#frameworks}}
{{#fetch-api}}
{{#platforms}}
{{#node}}
"node-fetch": "^2.6.0",
"@types/node-fetch": "^2.5.7",
{{/node}}
{{#browser}}
"whatwg-fetch": "^3.0.0",
{{/browser}}
{{/platforms}}
{{/fetch-api}}
{{#jquery}}
"@types/jquery": "^3.3.29",
"jquery": "^3.4.1",
{{/jquery}}
{{/frameworks}}
{{#platforms}}
{{#node}}
"@types/node": "*",
"form-data": "^2.5.0",
"btoa": "^1.2.1",
{{/node}}
{{/platforms}}
{{#useRxJS}}
"rxjs": "^6.4.0",
{{/useRxJS}}
"es6-promise": "^4.2.4",
"url-parse": "^1.4.3"
},
"devDependencies": {
"typescript": "^3.9.3"
}{{#npmRepository}},{{/npmRepository}}
{{#npmRepository}}
"publishConfig":{
"registry":"{{npmRepository}}"
}
{{/npmRepository}}
}

View File

@@ -1,27 +0,0 @@
export class Observable<T> {
constructor(private promise: Promise<T>) {}
toPromise() {
return this.promise;
}
pipe<S>(callback: (value: T) => S | Promise<S>): Observable<S> {
return new Observable(this.promise.then(callback));
}
}
export function from<T>(promise: Promise<any>) {
return new Observable(promise);
}
export function of<T>(value: T) {
return new Observable<T>(Promise.resolve(value));
}
export function mergeMap<T, S>(callback: (value: T) => Observable<S>) {
return (value: T) => callback(value).toPromise();
}
export function map(callback: any) {
return callback;
}

View File

@@ -1,36 +0,0 @@
{
"compilerOptions": {
"strict": true,
/* Basic Options */
"target": "{{#supportsES6}}es6{{/supportsES6}}{{^supportsES6}}es5{{/supportsES6}}",
"module": "{{#supportsES6}}es6{{/supportsES6}}{{^supportsES6}}commonjs{{/supportsES6}}",
"declaration": true,
/* Additional Checks */
"noUnusedLocals": false, /* Report errors on unused locals. */ // TODO: reenable (unused imports!)
"noUnusedParameters": false, /* Report errors on unused parameters. */ // TODO: set to true again
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
"noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
"removeComments": true,
"sourceMap": true,
"outDir": "./dist",
"noLib": false,
{{#platforms}}
{{#node}}
"lib": [ "es6" ]
{{/node}}
{{#browser}}
"lib": [ "es6", "dom" ]
{{/browser}}
{{/platforms}}
},
"exclude": [
"dist",
"node_modules"
],
"filesGlob": [
"./**/*.ts",
]
}

View File

@@ -1,60 +0,0 @@
import { ResponseContext, RequestContext, HttpFile } from '../http/http';
import * as models from '../models/all';
import { Configuration} from '../configuration'
{{#models}}
{{#model}}
import { {{{ classname }}} } from '../models/{{{ classFilename }}}';
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
{{#operations}}
import { Observable{{classname}} } from "./ObservableAPI";
import { {{classname}}RequestFactory, {{classname}}ResponseProcessor} from "../apis/{{classname}}";
{{#operation}}
export interface {{classname}}{{operationIdCamelCase}}Request {
{{#allParams}}
/**
* {{description}}
* @type {{dataType}}
* @memberof {{classname}}{{nickname}}
*/
{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}
{{/allParams}}
}
{{/operation}}
export class Object{{classname}} {
private api: Observable{{classname}}
public constructor(configuration: Configuration, requestFactory?: {{classname}}RequestFactory, responseProcessor?: {{classname}}ResponseProcessor) {
this.api = new Observable{{classname}}(configuration, requestFactory, responseProcessor);
}
{{#operation}}
/**
{{#notes}}
* {{&notes}}
{{/notes}}
{{#summary}}
* {{&summary}}
{{/summary}}
* @param param the request object
*/
public {{nickname}}(param: {{classname}}{{operationIdCamelCase}}Request, options?: Configuration): {{#useRxJS}}Observable{{/useRxJS}}{{^useRxJS}}Promise{{/useRxJS}}<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> {
return this.api.{{nickname}}({{#allParams}}param.{{paramName}}, {{/allParams}} options){{^useRxJS}}.toPromise(){{/useRxJS}};
}
{{/operation}}
}
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@@ -1,67 +0,0 @@
import { ResponseContext, RequestContext, HttpFile } from '../http/http';
import * as models from '../models/all';
import { Configuration} from '../configuration'
import { Observable, of, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub'{{/useRxJS}};
import {mergeMap, map} from {{#useRxJS}}'rxjs/operators'{{/useRxJS}}{{^useRxJS}}'../rxjsStub'{{/useRxJS}};
{{#models}}
{{#model}}
import { {{{ classname }}} } from '../models/{{{ classFilename }}}';
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
{{#operations}}
import { {{classname}}RequestFactory, {{classname}}ResponseProcessor} from "../apis/{{classname}}";
export class Observable{{classname}} {
private requestFactory: {{classname}}RequestFactory;
private responseProcessor: {{classname}}ResponseProcessor;
private configuration: Configuration;
public constructor(configuration: Configuration, requestFactory?: {{classname}}RequestFactory, responseProcessor?: {{classname}}ResponseProcessor) {
this.configuration = configuration;
this.requestFactory = requestFactory || new {{classname}}RequestFactory(configuration);
this.responseProcessor = responseProcessor || new {{classname}}ResponseProcessor();
}
{{#operation}}
/**
{{#notes}}
* {{&notes}}
{{/notes}}
{{#summary}}
* {{&summary}}
{{/summary}}
{{#allParams}}
* @param {{paramName}} {{description}}
{{/allParams}}
*/
public {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}options?: Configuration): Observable<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> {
const requestContextPromise = this.requestFactory.{{nickname}}({{#allParams}}{{paramName}}, {{/allParams}}options);
// build promise chain
let middlewarePreObservable = from<RequestContext>(requestContextPromise);
for (let middleware of this.configuration.middleware) {
middlewarePreObservable = middlewarePreObservable.pipe(mergeMap((ctx: RequestContext) => middleware.pre(ctx)));
}
return middlewarePreObservable.pipe(mergeMap((ctx: RequestContext) => this.configuration.httpApi.send(ctx))).
pipe(mergeMap((response: ResponseContext) => {
let middlewarePostObservable = of(response);
for (let middleware of this.configuration.middleware) {
middlewarePostObservable = middlewarePostObservable.pipe(mergeMap((rsp: ResponseContext) => middleware.post(rsp)));
}
return middlewarePostObservable.pipe(map((rsp: ResponseContext) => this.responseProcessor.{{nickname}}(rsp)));
}));
}
{{/operation}}
}
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@@ -1,49 +0,0 @@
import { ResponseContext, RequestContext, HttpFile } from '../http/http';
import * as models from '../models/all';
import { Configuration} from '../configuration'
{{#models}}
{{#model}}
import { {{{ classname }}} } from '../models/{{{ classFilename }}}';
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
import { Observable{{classname}} } from './ObservableAPI';
{{#operations}}
import { {{classname}}RequestFactory, {{classname}}ResponseProcessor} from "../apis/{{classname}}";
export class Promise{{classname}} {
private api: Observable{{classname}}
public constructor(configuration: Configuration, requestFactory?: {{classname}}RequestFactory, responseProcessor?: {{classname}}ResponseProcessor) {
this.api = new Observable{{classname}}(configuration, requestFactory, responseProcessor);
}
{{#operation}}
/**
{{#notes}}
* {{&notes}}
{{/notes}}
{{#summary}}
* {{&summary}}
{{/summary}}
{{#allParams}}
* @param {{paramName}} {{description}}
{{/allParams}}
*/
public {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}options?: Configuration): Promise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> {
const result = this.api.{{nickname}}({{#allParams}}{{paramName}}, {{/allParams}}options);
return result.toPromise();
}
{{/operation}}
}
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@@ -1,28 +0,0 @@
/**
* Returns if a specific http code is in a given code range
* where the code range is defined as a combination of digits
* and "X" (the letter X) with a length of 3
*
* @param codeRange string with length 3 consisting of digits and "X" (the letter X)
* @param code the http status code to be checked against the code range
*/
export function isCodeInRange(codeRange: string, code: number): boolean {
// This is how the default value is encoded in OAG
if (codeRange === "0") {
return true;
}
if (codeRange == code.toString()) {
return true;
} else {
const codeString = code.toString();
if (codeString.length != codeRange.length) {
return false;
}
for (let i = 0; i < codeString.length; i++) {
if (codeRange.charAt(i) != "X" && codeRange.charAt(i) != codeString.charAt(i)) {
return false;
}
}
return true;
}
}

View File

@@ -21,8 +21,10 @@ import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.parser.util.SchemaTypeUtil;
import java.time.OffsetDateTime;
import org.openapitools.codegen.*;
import org.openapitools.codegen.languages.PythonClientExperimentalCodegen;
import org.openapitools.codegen.utils.ModelUtils;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -268,7 +270,7 @@ public class PythonClientExperimentalTest {
Assert.assertEquals(cm.classname, "sample.Sample");
Assert.assertEquals(cm.classVarName, "sample");
Assert.assertEquals(cm.description, "an array model");
Assert.assertEquals(cm.vars.size(), 0);
Assert.assertEquals(cm.vars.size(), 1); // there is one value for Childer definition
Assert.assertEquals(cm.parent, "list");
Assert.assertEquals(cm.imports.size(), 1);
Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("children.Children")).size(), 1);
@@ -293,4 +295,14 @@ public class PythonClientExperimentalTest {
Assert.assertEquals(cm.imports.size(), 0);
}
@Test(description = "parse date and date-time example value")
public void parseDateAndDateTimeExamplesTest() {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/python-experimental/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml");
final DefaultCodegen codegen = new PythonClientExperimentalCodegen();
Schema modelSchema = ModelUtils.getSchema(openAPI, "DateTimeTest");
String defaultValue = codegen.toDefaultValue(modelSchema);
Assert.assertEquals(defaultValue, "dateutil_parser('2010-01-01T10:10:10.000111+01:00')");
}
}

View File

@@ -1810,6 +1810,7 @@ components:
type: string
banana:
type: object
additionalProperties: true
properties:
lengthCm:
type: number

View File

@@ -699,6 +699,7 @@ components:
xml:
name: User
Tag:
additionalProperties: true
title: Pet Tag
description: A tag for a pet
type: object

View File

@@ -758,6 +758,8 @@ paths:
description: None
type: string
format: date-time
default: '2010-02-01T10:20:10.11111+01:00'
example: '2020-02-02T20:20:20.22222Z'
password:
description: None
type: string
@@ -1097,6 +1099,19 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/HealthCheckResult'
/fake/array-of-enums:
get:
tags:
- fake
summary: Array of Enums
operationId: getArrayOfEnums
responses:
200:
description: Got named array of enums
content:
application/json:
schema:
$ref: '#/components/schemas/ArrayOfEnums'
servers:
- url: 'http://{server}.swagger.io:{port}/v2'
description: petstore server
@@ -1202,6 +1217,7 @@ components:
shipDate:
type: string
format: date-time
example: '2020-02-02T20:20:20.000222Z'
status:
type: string
description: Order Status
@@ -1443,7 +1459,7 @@ components:
maximum: 543.2
minimum: 32.1
type: number
multipleOf: 32.5
multipleOf: 32.5
float:
type: number
format: float
@@ -1466,9 +1482,11 @@ components:
date:
type: string
format: date
example: '2020-02-02'
dateTime:
type: string
format: date-time
example: '2007-12-03T10:15:30+01:00'
uuid:
type: string
format: uuid
@@ -1969,7 +1987,7 @@ components:
# Here the additional properties are specified using a referenced schema.
# This is just to validate the generated code works when using $ref
# under 'additionalProperties'.
$ref: '#/components/schemas/fruit'
$ref: '#/components/schemas/fruit'
Shape:
oneOf:
- $ref: '#/components/schemas/Triangle'
@@ -2069,3 +2087,12 @@ components:
properties:
name:
type: string
ArrayOfEnums:
type: array
items:
$ref: '#/components/schemas/OuterEnum'
DateTimeTest:
type: string
default: '2010-01-01T10:10:10.000111+01:00'
example: '2010-01-01T10:10:10.000111+01:00'
format: date-time

32
pom.xml
View File

@@ -956,30 +956,6 @@
<module>samples/server/petstore/jaxrs-spec-interface-response</module>
</modules>
</profile>
<profile>
<id>typescript-client-tests-default</id>
<activation>
<property>
<name>env</name>
<value>java</value>
</property>
</activation>
<modules>
<module>samples/openapi3/client/petstore/typescript/tests/default</module>
</modules>
</profile>
<profile>
<id>typescript-client-tests-jquery</id>
<activation>
<property>
<name>env</name>
<value>java</value>
</property>
</activation>
<modules>
<module>samples/openapi3/client/petstore/typescript/tests/jquery</module>
</modules>
</profile>
<profile>
<id>typescript-fetch-client-tests-default</id>
<activation>
@@ -1244,12 +1220,6 @@
<module>samples/client/petstore/python-tornado</module>
<module>samples/openapi3/client/petstore/python</module>
<module>samples/openapi3/client/petstore/python-experimental</module>
<module>samples/openapi3/client/petstore/typescript/builds/default</module>
<module>samples/openapi3/client/petstore/typescript/tests/default</module>
<module>samples/openapi3/client/petstore/typescript/builds/jquery</module>
<module>samples/openapi3/client/petstore/typescript/tests/jquery</module>
<module>samples/openapi3/client/petstore/typescript/builds/object_params</module>
<module>samples/openapi3/client/petstore/typescript/tests/object_params</module>
<module>samples/client/petstore/typescript-fetch/builds/default</module>
<module>samples/client/petstore/typescript-fetch/builds/es6-target</module>
<module>samples/client/petstore/typescript-fetch/builds/with-npm-version</module>
@@ -1294,7 +1264,7 @@
<module>samples/client/petstore/java/feign10x</module>
<module>samples/client/petstore/java/jersey1</module>
<module>samples/client/petstore/java/jersey2-java8</module>
<module>samples/openapi3/client/petstore/java/jersey2-java8</module>
<!--<module>samples/openapi3/client/petstore/java/jersey2-java8</module>-->
<module>samples/client/petstore/java/okhttp-gson</module>
<module>samples/client/petstore/java/retrofit2</module>
<module>samples/client/petstore/java/retrofit2rx</module>

View File

@@ -26,5 +26,6 @@ public class OpenAPI : ModuleRules
"Json",
}
);
PCHUsage = PCHUsageMode.NoPCHs;
}
}

View File

@@ -38,14 +38,19 @@ void OpenAPIApiResponse::WriteJson(JsonWriter& Writer) const
Writer->WriteObjectEnd();
}
bool OpenAPIApiResponse::FromJson(const TSharedPtr<FJsonObject>& JsonObject)
bool OpenAPIApiResponse::FromJson(const TSharedPtr<FJsonValue>& JsonValue)
{
const TSharedPtr<FJsonObject>* Object;
if (!JsonValue->TryGetObject(Object))
return false;
bool ParseSuccess = true;
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("code"), Code);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("type"), Type);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("message"), Message);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("code"), Code);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("type"), Type);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("message"), Message);
return ParseSuccess;
}
}

View File

@@ -34,13 +34,18 @@ void OpenAPICategory::WriteJson(JsonWriter& Writer) const
Writer->WriteObjectEnd();
}
bool OpenAPICategory::FromJson(const TSharedPtr<FJsonObject>& JsonObject)
bool OpenAPICategory::FromJson(const TSharedPtr<FJsonValue>& JsonValue)
{
const TSharedPtr<FJsonObject>* Object;
if (!JsonValue->TryGetObject(Object))
return false;
bool ParseSuccess = true;
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("id"), Id);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("name"), Name);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("id"), Id);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("name"), Name);
return ParseSuccess;
}
}

View File

@@ -17,6 +17,7 @@
#include "Interfaces/IHttpRequest.h"
#include "PlatformHttp.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
namespace OpenAPI
{

View File

@@ -96,17 +96,22 @@ void OpenAPIOrder::WriteJson(JsonWriter& Writer) const
Writer->WriteObjectEnd();
}
bool OpenAPIOrder::FromJson(const TSharedPtr<FJsonObject>& JsonObject)
bool OpenAPIOrder::FromJson(const TSharedPtr<FJsonValue>& JsonValue)
{
const TSharedPtr<FJsonObject>* Object;
if (!JsonValue->TryGetObject(Object))
return false;
bool ParseSuccess = true;
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("id"), Id);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("petId"), PetId);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("quantity"), Quantity);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("shipDate"), ShipDate);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("status"), Status);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("complete"), Complete);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("id"), Id);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("petId"), PetId);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("quantity"), Quantity);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("shipDate"), ShipDate);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("status"), Status);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("complete"), Complete);
return ParseSuccess;
}
}

View File

@@ -90,17 +90,22 @@ void OpenAPIPet::WriteJson(JsonWriter& Writer) const
Writer->WriteObjectEnd();
}
bool OpenAPIPet::FromJson(const TSharedPtr<FJsonObject>& JsonObject)
bool OpenAPIPet::FromJson(const TSharedPtr<FJsonValue>& JsonValue)
{
const TSharedPtr<FJsonObject>* Object;
if (!JsonValue->TryGetObject(Object))
return false;
bool ParseSuccess = true;
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("id"), Id);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("category"), Category);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("name"), Name);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("photoUrls"), PhotoUrls);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("tags"), Tags);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("status"), Status);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("id"), Id);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("category"), Category);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("name"), Name);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("photoUrls"), PhotoUrls);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("tags"), Tags);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("status"), Status);
return ParseSuccess;
}
}

View File

@@ -34,13 +34,18 @@ void OpenAPITag::WriteJson(JsonWriter& Writer) const
Writer->WriteObjectEnd();
}
bool OpenAPITag::FromJson(const TSharedPtr<FJsonObject>& JsonObject)
bool OpenAPITag::FromJson(const TSharedPtr<FJsonValue>& JsonValue)
{
const TSharedPtr<FJsonObject>* Object;
if (!JsonValue->TryGetObject(Object))
return false;
bool ParseSuccess = true;
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("id"), Id);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("name"), Name);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("id"), Id);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("name"), Name);
return ParseSuccess;
}
}

View File

@@ -58,19 +58,24 @@ void OpenAPIUser::WriteJson(JsonWriter& Writer) const
Writer->WriteObjectEnd();
}
bool OpenAPIUser::FromJson(const TSharedPtr<FJsonObject>& JsonObject)
bool OpenAPIUser::FromJson(const TSharedPtr<FJsonValue>& JsonValue)
{
const TSharedPtr<FJsonObject>* Object;
if (!JsonValue->TryGetObject(Object))
return false;
bool ParseSuccess = true;
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("id"), Id);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("username"), Username);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("firstName"), FirstName);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("lastName"), LastName);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("email"), Email);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("password"), Password);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("phone"), Phone);
ParseSuccess &= TryGetJsonValue(JsonObject, TEXT("userStatus"), UserStatus);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("id"), Id);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("username"), Username);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("firstName"), FirstName);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("lastName"), LastName);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("email"), Email);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("password"), Password);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("phone"), Phone);
ParseSuccess &= TryGetJsonValue(*Object, TEXT("userStatus"), UserStatus);
return ParseSuccess;
}
}

View File

@@ -26,7 +26,7 @@ class OPENAPI_API OpenAPIApiResponse : public Model
{
public:
virtual ~OpenAPIApiResponse() {}
bool FromJson(const TSharedPtr<FJsonObject>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
void WriteJson(JsonWriter& Writer) const final;
TOptional<int32> Code;

View File

@@ -27,7 +27,7 @@ class OPENAPI_API Model
public:
virtual ~Model() {}
virtual void WriteJson(JsonWriter& Writer) const = 0;
virtual bool FromJson(const TSharedPtr<FJsonObject>& JsonObject) = 0;
virtual bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) = 0;
};
class OPENAPI_API Request
@@ -42,7 +42,7 @@ class OPENAPI_API Response
{
public:
virtual ~Response() {}
virtual bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) = 0;
virtual bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) = 0;
void SetSuccessful(bool InSuccessful) { Successful = InSuccessful; }
bool IsSuccessful() const { return Successful; }

View File

@@ -26,7 +26,7 @@ class OPENAPI_API OpenAPICategory : public Model
{
public:
virtual ~OpenAPICategory() {}
bool FromJson(const TSharedPtr<FJsonObject>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
void WriteJson(JsonWriter& Writer) const final;
TOptional<int64> Id;

View File

@@ -17,6 +17,7 @@
#include "Serialization/JsonSerializer.h"
#include "Dom/JsonObject.h"
#include "Misc/Base64.h"
#include "PlatformHttp.h"
class IHttpRequest;
@@ -205,10 +206,22 @@ inline FString CollectionToUrlString_multi(const TArray<T>& Collection, const TC
//////////////////////////////////////////////////////////////////////////
template<typename T, typename std::enable_if<!std::is_base_of<Model, T>::value, int>::type = 0>
inline void WriteJsonValue(JsonWriter& Writer, const T& Value)
inline void WriteJsonValue(JsonWriter& Writer, const TSharedPtr<FJsonObject>& Value)
{
Writer->WriteValue(Value);
if (Value.IsValid())
{
FJsonSerializer::Serialize(Value.ToSharedRef(), Writer, false);
}
else
{
Writer->WriteObjectStart();
Writer->WriteObjectEnd();
}
}
inline void WriteJsonValue(JsonWriter& Writer, const TArray<uint8>& Value)
{
Writer->WriteValue(ToString(Value));
}
inline void WriteJsonValue(JsonWriter& Writer, const FDateTime& Value)
@@ -221,6 +234,12 @@ inline void WriteJsonValue(JsonWriter& Writer, const Model& Value)
Value.WriteJson(Writer);
}
template<typename T, typename std::enable_if<!std::is_base_of<Model, T>::value, int>::type = 0>
inline void WriteJsonValue(JsonWriter& Writer, const T& Value)
{
Writer->WriteValue(Value);
}
template<typename T>
inline void WriteJsonValue(JsonWriter& Writer, const TArray<T>& Value)
{
@@ -244,54 +263,8 @@ inline void WriteJsonValue(JsonWriter& Writer, const TMap<FString, T>& Value)
Writer->WriteObjectEnd();
}
inline void WriteJsonValue(JsonWriter& Writer, const TSharedPtr<FJsonObject>& Value)
{
if (Value.IsValid())
{
FJsonSerializer::Serialize(Value.ToSharedRef(), Writer, false);
}
else
{
Writer->WriteObjectStart();
Writer->WriteObjectEnd();
}
}
inline void WriteJsonValue(JsonWriter& Writer, const TArray<uint8>& Value)
{
Writer->WriteValue(ToString(Value));
}
//////////////////////////////////////////////////////////////////////////
template<typename T>
inline bool TryGetJsonValue(const TSharedPtr<FJsonObject>& JsonObject, const FString& Key, T& Value)
{
const TSharedPtr<FJsonValue> JsonValue = JsonObject->TryGetField(Key);
if (JsonValue.IsValid() && !JsonValue->IsNull())
{
return TryGetJsonValue(JsonValue, Value);
}
return false;
}
template<typename T>
inline bool TryGetJsonValue(const TSharedPtr<FJsonObject>& JsonObject, const FString& Key, TOptional<T>& OptionalValue)
{
if(JsonObject->HasField(Key))
{
T Value;
if (TryGetJsonValue(JsonObject, Key, Value))
{
OptionalValue = Value;
return true;
}
else
return false;
}
return true; // Absence of optional value is not a parsing error
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, FString& Value)
{
FString TmpValue;
@@ -325,6 +298,34 @@ inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, bool& Value
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, TSharedPtr<FJsonObject>& JsonObjectValue)
{
const TSharedPtr<FJsonObject>* Object;
if (JsonValue->TryGetObject(Object))
{
JsonObjectValue = *Object;
return true;
}
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, TArray<uint8>& Value)
{
FString TmpValue;
if (JsonValue->TryGetString(TmpValue))
{
Base64UrlDecode(TmpValue, Value);
return true;
}
else
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, Model& Value)
{
return Value.FromJson(JsonValue);
}
template<typename T, typename std::enable_if<!std::is_base_of<Model, T>::value, int>::type = 0>
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, T& Value)
{
@@ -338,15 +339,6 @@ inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, T& Value)
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, Model& Value)
{
const TSharedPtr<FJsonObject>* Object;
if (JsonValue->TryGetObject(Object))
return Value.FromJson(*Object);
else
return false;
}
template<typename T>
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, TArray<T>& ArrayValue)
{
@@ -386,27 +378,32 @@ inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, TMap<FStrin
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, TSharedPtr<FJsonObject>& JsonObjectValue)
template<typename T>
inline bool TryGetJsonValue(const TSharedPtr<FJsonObject>& JsonObject, const FString& Key, T& Value)
{
const TSharedPtr<FJsonObject>* Object;
if (JsonValue->TryGetObject(Object))
const TSharedPtr<FJsonValue> JsonValue = JsonObject->TryGetField(Key);
if (JsonValue.IsValid() && !JsonValue->IsNull())
{
JsonObjectValue = *Object;
return true;
return TryGetJsonValue(JsonValue, Value);
}
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, TArray<uint8>& Value)
template<typename T>
inline bool TryGetJsonValue(const TSharedPtr<FJsonObject>& JsonObject, const FString& Key, TOptional<T>& OptionalValue)
{
FString TmpValue;
if (JsonValue->TryGetString(TmpValue))
if(JsonObject->HasField(Key))
{
Base64UrlDecode(TmpValue, Value);
return true;
T Value;
if (TryGetJsonValue(JsonObject, Key, Value))
{
OptionalValue = Value;
return true;
}
else
return false;
}
else
return false;
return true; // Absence of optional value is not a parsing error
}
}

View File

@@ -26,7 +26,7 @@ class OPENAPI_API OpenAPIOrder : public Model
{
public:
virtual ~OpenAPIOrder() {}
bool FromJson(const TSharedPtr<FJsonObject>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
void WriteJson(JsonWriter& Writer) const final;
TOptional<int64> Id;

View File

@@ -28,7 +28,7 @@ class OPENAPI_API OpenAPIPet : public Model
{
public:
virtual ~OpenAPIPet() {}
bool FromJson(const TSharedPtr<FJsonObject>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
void WriteJson(JsonWriter& Writer) const final;
TOptional<int64> Id;

View File

@@ -41,7 +41,7 @@ class OPENAPI_API OpenAPIPetApi::AddPetResponse : public Response
public:
virtual ~AddPetResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
};
@@ -66,7 +66,7 @@ class OPENAPI_API OpenAPIPetApi::DeletePetResponse : public Response
public:
virtual ~DeletePetResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
};
@@ -97,7 +97,7 @@ class OPENAPI_API OpenAPIPetApi::FindPetsByStatusResponse : public Response
public:
virtual ~FindPetsByStatusResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
TArray<OpenAPIPet> Content;
};
@@ -122,7 +122,7 @@ class OPENAPI_API OpenAPIPetApi::FindPetsByTagsResponse : public Response
public:
virtual ~FindPetsByTagsResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
TArray<OpenAPIPet> Content;
};
@@ -147,7 +147,7 @@ class OPENAPI_API OpenAPIPetApi::GetPetByIdResponse : public Response
public:
virtual ~GetPetByIdResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
OpenAPIPet Content;
};
@@ -171,7 +171,7 @@ class OPENAPI_API OpenAPIPetApi::UpdatePetResponse : public Response
public:
virtual ~UpdatePetResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
};
@@ -199,7 +199,7 @@ class OPENAPI_API OpenAPIPetApi::UpdatePetWithFormResponse : public Response
public:
virtual ~UpdatePetWithFormResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
};
@@ -227,7 +227,7 @@ class OPENAPI_API OpenAPIPetApi::UploadFileResponse : public Response
public:
virtual ~UploadFileResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
OpenAPIApiResponse Content;
};

View File

@@ -40,7 +40,7 @@ class OPENAPI_API OpenAPIStoreApi::DeleteOrderResponse : public Response
public:
virtual ~DeleteOrderResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
};
@@ -63,7 +63,7 @@ class OPENAPI_API OpenAPIStoreApi::GetInventoryResponse : public Response
public:
virtual ~GetInventoryResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
TMap<FString, int32> Content;
};
@@ -88,7 +88,7 @@ class OPENAPI_API OpenAPIStoreApi::GetOrderByIdResponse : public Response
public:
virtual ~GetOrderByIdResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
OpenAPIOrder Content;
};
@@ -112,7 +112,7 @@ class OPENAPI_API OpenAPIStoreApi::PlaceOrderResponse : public Response
public:
virtual ~PlaceOrderResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
OpenAPIOrder Content;
};

View File

@@ -26,7 +26,7 @@ class OPENAPI_API OpenAPITag : public Model
{
public:
virtual ~OpenAPITag() {}
bool FromJson(const TSharedPtr<FJsonObject>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
void WriteJson(JsonWriter& Writer) const final;
TOptional<int64> Id;

View File

@@ -26,7 +26,7 @@ class OPENAPI_API OpenAPIUser : public Model
{
public:
virtual ~OpenAPIUser() {}
bool FromJson(const TSharedPtr<FJsonObject>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
void WriteJson(JsonWriter& Writer) const final;
TOptional<int64> Id;

View File

@@ -40,7 +40,7 @@ class OPENAPI_API OpenAPIUserApi::CreateUserResponse : public Response
public:
virtual ~CreateUserResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
};
@@ -64,7 +64,7 @@ class OPENAPI_API OpenAPIUserApi::CreateUsersWithArrayInputResponse : public Res
public:
virtual ~CreateUsersWithArrayInputResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
};
@@ -88,7 +88,7 @@ class OPENAPI_API OpenAPIUserApi::CreateUsersWithListInputResponse : public Resp
public:
virtual ~CreateUsersWithListInputResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
};
@@ -113,7 +113,7 @@ class OPENAPI_API OpenAPIUserApi::DeleteUserResponse : public Response
public:
virtual ~DeleteUserResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
};
@@ -137,7 +137,7 @@ class OPENAPI_API OpenAPIUserApi::GetUserByNameResponse : public Response
public:
virtual ~GetUserByNameResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
OpenAPIUser Content;
};
@@ -163,7 +163,7 @@ class OPENAPI_API OpenAPIUserApi::LoginUserResponse : public Response
public:
virtual ~LoginUserResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
FString Content;
};
@@ -185,7 +185,7 @@ class OPENAPI_API OpenAPIUserApi::LogoutUserResponse : public Response
public:
virtual ~LogoutUserResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
};
@@ -212,7 +212,7 @@ class OPENAPI_API OpenAPIUserApi::UpdateUserResponse : public Response
public:
virtual ~UpdateUserResponse() {}
void SetHttpResponseCode(EHttpResponseCodes::Type InHttpResponseCode) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonObject) final;
bool FromJson(const TSharedPtr<FJsonValue>& JsonValue) final;
};

View File

@@ -147,3 +147,4 @@ func (v *NullableModel200Response) UnmarshalJSON(src []byte) error {
return json.Unmarshal(src, &v.value)
}

View File

@@ -16,8 +16,11 @@ import (
// AdditionalPropertiesAnyType struct for AdditionalPropertiesAnyType
type AdditionalPropertiesAnyType struct {
Name *string `json:"name,omitempty"`
AdditionalProperties map[string]interface{}
}
type _AdditionalPropertiesAnyType AdditionalPropertiesAnyType
// NewAdditionalPropertiesAnyType instantiates a new AdditionalPropertiesAnyType object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
@@ -72,9 +75,31 @@ func (o AdditionalPropertiesAnyType) MarshalJSON() ([]byte, error) {
if o.Name != nil {
toSerialize["name"] = o.Name
}
for key, value := range o.AdditionalProperties {
toSerialize[key] = value
}
return json.Marshal(toSerialize)
}
func (o *AdditionalPropertiesAnyType) UnmarshalJSON(bytes []byte) (err error) {
varAdditionalPropertiesAnyType := _AdditionalPropertiesAnyType{}
if err = json.Unmarshal(bytes, &varAdditionalPropertiesAnyType); err == nil {
*o = AdditionalPropertiesAnyType(varAdditionalPropertiesAnyType)
}
additionalProperties := make(map[string]interface{})
if err = json.Unmarshal(bytes, &additionalProperties); err == nil {
delete(additionalProperties, "name")
o.AdditionalProperties = additionalProperties
}
return err
}
type NullableAdditionalPropertiesAnyType struct {
value *AdditionalPropertiesAnyType
isSet bool
@@ -111,3 +136,4 @@ func (v *NullableAdditionalPropertiesAnyType) UnmarshalJSON(src []byte) error {
return json.Unmarshal(src, &v.value)
}

View File

@@ -111,3 +111,4 @@ func (v *NullableAdditionalPropertiesArray) UnmarshalJSON(src []byte) error {
return json.Unmarshal(src, &v.value)
}

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