forked from loafle/openapi-generator-original
Compare commits
58 Commits
v4.2.0
...
typescript
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3f5fef279 | ||
|
|
6dfe637b21 | ||
|
|
a738e95aee | ||
|
|
9d08f8bc5b | ||
|
|
9e49c7e942 | ||
|
|
bc734da7d4 | ||
|
|
abff890b90 | ||
|
|
b796270880 | ||
|
|
02c1d9ff64 | ||
|
|
7d69d0b9cb | ||
|
|
3e94fd15cc | ||
|
|
491fae4c25 | ||
|
|
be3e24b681 | ||
|
|
7d0b3e1879 | ||
|
|
8b138ecd81 | ||
|
|
496c0c8bdc | ||
|
|
b8e31fcddd | ||
|
|
64b8505010 | ||
|
|
5f163da848 | ||
|
|
7f5615485d | ||
|
|
e700a08a8f | ||
|
|
74bb8ccfe7 | ||
|
|
01b0ff6008 | ||
|
|
5323a5d7a6 | ||
|
|
8c03ea8ca5 | ||
|
|
c90c3f9d7b | ||
|
|
9c17bc5721 | ||
|
|
a0e3f18f2f | ||
|
|
647474f3d9 | ||
|
|
4720467cbb | ||
|
|
2468b748d3 | ||
|
|
9a9e62cfa5 | ||
|
|
5174e7539b | ||
|
|
fe0cb07afb | ||
|
|
878ea6e1c1 | ||
|
|
69dfdd57a6 | ||
|
|
502e209bfe | ||
|
|
8d29ca42d5 | ||
|
|
49219fa48a | ||
|
|
f4b3eb011b | ||
|
|
ef065f3013 | ||
|
|
29940ef0b1 | ||
|
|
dd7d8c0271 | ||
|
|
0da5238e24 | ||
|
|
2e8446ceee | ||
|
|
662242157f | ||
|
|
5adefaf53f | ||
|
|
8dca5e4cbe | ||
|
|
e21a48dd64 | ||
|
|
894bddac1b | ||
|
|
fe2cc24f4d | ||
|
|
b0f8dc9505 | ||
|
|
8f82cdec7d | ||
|
|
64f29483ce | ||
|
|
94432cff92 | ||
|
|
3e745b71f2 | ||
|
|
f90e1b59f5 | ||
|
|
dd6835393d |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,6 +7,7 @@ out/
|
||||
classpath.txt
|
||||
version.properties
|
||||
modules/openapi-generator-gradle-plugin/bin/
|
||||
modules/openapi-generator-cli/bin/
|
||||
!modules/openapi-generator-cli/src/main/resources/version.properties
|
||||
.project
|
||||
.classpath
|
||||
|
||||
@@ -20,6 +20,7 @@ cache:
|
||||
- $HOME/samples/client/petstore/php/OpenAPIToolsClient-php/vendor
|
||||
- $HOME/samples/client/petstore/ruby/vendor/bundle
|
||||
- $HOME/samples/client/petstore/python/.venv/
|
||||
- $HOME/samples/client/petstore/typescript/tests/default/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
|
||||
|
||||
12
README.md
12
README.md
@@ -159,16 +159,16 @@ See the different versions of the [openapi-generator-cli](https://mvnrepository.
|
||||
<!-- RELEASE_VERSION -->
|
||||
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum):
|
||||
|
||||
JAR location: `http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.2.0/openapi-generator-cli-4.2.0.jar`
|
||||
JAR location: `http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.1.3/openapi-generator-cli-4.1.3.jar`
|
||||
|
||||
For **Mac/Linux** users:
|
||||
```sh
|
||||
wget http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.2.0/openapi-generator-cli-4.2.0.jar -O openapi-generator-cli.jar
|
||||
wget http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.1.3/openapi-generator-cli-4.1.3.jar -O openapi-generator-cli.jar
|
||||
```
|
||||
|
||||
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
|
||||
```
|
||||
Invoke-WebRequest -OutFile openapi-generator-cli.jar http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.2.0/openapi-generator-cli-4.2.0.jar
|
||||
Invoke-WebRequest -OutFile openapi-generator-cli.jar http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.1.3/openapi-generator-cli-4.1.3.jar
|
||||
```
|
||||
|
||||
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
|
||||
@@ -383,10 +383,10 @@ openapi-generator version
|
||||
```
|
||||
|
||||
<!-- RELEASE_VERSION -->
|
||||
Or install a particular OpenAPI Generator version (e.g. v4.2.0):
|
||||
Or install a particular OpenAPI Generator version (e.g. v4.1.3):
|
||||
|
||||
```sh
|
||||
npm install @openapitools/openapi-generator-cli@cli-4.2.0 -g
|
||||
npm install @openapitools/openapi-generator-cli@cli-4.1.3 -g
|
||||
```
|
||||
|
||||
Or install it as dev-dependency:
|
||||
@@ -410,7 +410,7 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat
|
||||
(if you're on Windows, replace the last command with `java -jar modules\openapi-generator-cli\target\openapi-generator-cli.jar generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g php -o c:\temp\php_api_client`)
|
||||
|
||||
<!-- RELEASE_VERSION -->
|
||||
You can also download the JAR (latest release) directly from [maven.org](http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.2.0/openapi-generator-cli-4.2.0.jar)
|
||||
You can also download the JAR (latest release) directly from [maven.org](http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.1.3/openapi-generator-cli-4.1.3.jar)
|
||||
<!-- /RELEASE_VERSION -->
|
||||
|
||||
To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate`
|
||||
|
||||
37
bin/typescript.sh
Executable file
37
bin/typescript.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
|
||||
SCRIPT="$0"
|
||||
echo "# START SCRIPT: $SCRIPT"
|
||||
|
||||
while [ -h "$SCRIPT" ] ; do
|
||||
ls=`ls -ld "$SCRIPT"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
SCRIPT="$link"
|
||||
else
|
||||
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -d "${APP_DIR}" ]; then
|
||||
APP_DIR=`dirname "$SCRIPT"`/..
|
||||
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||
fi
|
||||
|
||||
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
|
||||
|
||||
if [ ! -f "$executable" ]
|
||||
then
|
||||
mvn -B clean package
|
||||
fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
echo "Creating default (fetch) client!"
|
||||
ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g typescript -o samples/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/2_0/petstore.yaml -g typescript -o samples/client/petstore/typescript/builds/jquery --additional-properties=framework=jquery,npmName=ts-petstore-client $@"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
@@ -73,6 +73,7 @@ declare -a scripts=(
|
||||
"./bin/java-play-framework-petstore-server-all.sh"
|
||||
"./bin/elm-petstore-all.sh"
|
||||
"./bin/meta-codegen.sh"
|
||||
"./bin/typescript.sh"
|
||||
# OTHERS
|
||||
"./bin/utils/export_docs_generators.sh"
|
||||
"./bin/utils/copy-to-website.sh"
|
||||
|
||||
@@ -57,6 +57,7 @@ The following generators are available:
|
||||
* [swift2-deprecated (deprecated)](generators/swift2-deprecated.md)
|
||||
* [swift3-deprecated (deprecated)](generators/swift3-deprecated.md)
|
||||
* [swift4](generators/swift4.md)
|
||||
* [typescript](generators/typescript.md)
|
||||
* [typescript-angular](generators/typescript-angular.md)
|
||||
* [typescript-angularjs](generators/typescript-angularjs.md)
|
||||
* [typescript-aurelia](generators/typescript-aurelia.md)
|
||||
|
||||
@@ -11,4 +11,3 @@ sidebar_label: haskell
|
||||
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|
||||
|modelPackage|package for generated models| |null|
|
||||
|apiPackage|package for generated api classes| |null|
|
||||
|serveStatic|serve will serve files from the directory 'static'.| |true|
|
||||
|
||||
17
docs/generators/typescript.md
Normal file
17
docs/generators/typescript.md
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: Config Options for typescript
|
||||
sidebar_label: typescript
|
||||
---
|
||||
|
||||
| Option | Description | Values | Default |
|
||||
| ------ | ----------- | ------ | ------- |
|
||||
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|
||||
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|
||||
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|
||||
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|
||||
|modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase|
|
||||
|supportsES6|Generate code that conforms to ES6.| |false|
|
||||
|fileContentDataType|Specifies the type to use for the content of a file - i.e. Blob (Browser) / Buffer (node)| |Buffer|
|
||||
|useRxJS|Enable this to internally use rxjs observables. If disabled, a stub is used instead. This is required for the 'angular' framework.| |false|
|
||||
|platform|Specifies the platform the code should run on. The default is 'node' for the 'request' framework and 'browser' otherwise.| |null|
|
||||
|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|
|
||||
@@ -4,7 +4,7 @@
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-project</artifactId>
|
||||
<!-- RELEASE_VERSION -->
|
||||
<version>4.2.0</version>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<!-- /RELEASE_VERSION -->
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<artifactId>openapi-generator-project</artifactId>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<!-- RELEASE_VERSION -->
|
||||
<version>4.2.0</version>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<!-- /RELEASE_VERSION -->
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -45,7 +45,7 @@ compileJava.dependsOn tasks.openApiGenerate
|
||||
[source,group]
|
||||
----
|
||||
plugins {
|
||||
id "org.openapi.generator" version "4.2.0"
|
||||
id "org.openapi.generator" version "4.1.1"
|
||||
}
|
||||
----
|
||||
|
||||
@@ -61,7 +61,7 @@ buildscript {
|
||||
// url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.openapitools:openapi-generator-gradle-plugin:4.2.0"
|
||||
classpath "org.openapitools:openapi-generator-gradle-plugin:4.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,7 +626,7 @@ buildscript {
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath('org.openapitools:openapi-generator-gradle-plugin:4.2.0') {
|
||||
classpath('org.openapitools:openapi-generator-gradle-plugin:4.1.1') {
|
||||
exclude group: 'com.google.guava'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# RELEASE_VERSION
|
||||
openApiGeneratorVersion=4.2.0
|
||||
openApiGeneratorVersion=4.2.0-SNAPSHOT
|
||||
# /RELEASE_VERSION
|
||||
|
||||
# BEGIN placeholders
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-project</artifactId>
|
||||
<!-- RELEASE_VERSION -->
|
||||
<version>4.2.0</version>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<!-- /RELEASE_VERSION -->
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,5 +17,5 @@ gradle generateGoWithInvalidSpec
|
||||
The samples can be tested against other versions of the plugin using the `openApiGeneratorVersion` property. For example:
|
||||
|
||||
```bash
|
||||
gradle -PopenApiGeneratorVersion=4.2.0 openApiValidate
|
||||
gradle -PopenApiGeneratorVersion=4.1.1 openApiValidate
|
||||
```
|
||||
|
||||
@@ -12,7 +12,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||
<!-- RELEASE_VERSION -->
|
||||
<version>4.2.0</version>
|
||||
<version>4.1.1</version>
|
||||
<!-- /RELEASE_VERSION -->
|
||||
<executions>
|
||||
<execution>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-project</artifactId>
|
||||
<!-- RELEASE_VERSION -->
|
||||
<version>4.2.0</version>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<!-- /RELEASE_VERSION -->
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-project</artifactId>
|
||||
<!-- RELEASE_VERSION -->
|
||||
<version>4.2.0</version>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<!-- /RELEASE_VERSION -->
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-project</artifactId>
|
||||
<!-- RELEASE_VERSION -->
|
||||
<version>4.2.0</version>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<!-- /RELEASE_VERSION -->
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -30,8 +30,8 @@ public class CodegenOperation {
|
||||
isResponseBinary = false, isResponseFile = false, hasReference = false,
|
||||
isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
|
||||
isRestful, isDeprecated, isCallbackRequest;
|
||||
public String path, operationId, returnType, httpMethod, returnBaseType,
|
||||
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
|
||||
public String path, operationId, returnType, returnFormat, 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>();
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.*;
|
||||
public class CodegenResponse {
|
||||
public final List<CodegenProperty> headers = new ArrayList<CodegenProperty>();
|
||||
public String code, message;
|
||||
public boolean isSuccessCode;
|
||||
public boolean hasMore;
|
||||
public List<Map<String, Object>> examples;
|
||||
public String dataType, baseType, containerType;
|
||||
|
||||
@@ -2547,7 +2547,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.hasReference = schemas.containsKey(op.returnBaseType);
|
||||
op.returnFormat = cm.dataFormat;
|
||||
op.hasReference = schemas != null && schemas.containsKey(op.returnBaseType);
|
||||
|
||||
// lookup discriminator
|
||||
Schema schema = schemas.get(op.returnBaseType);
|
||||
@@ -2869,6 +2870,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
r.code = "0";
|
||||
} else {
|
||||
r.code = responseCode;
|
||||
r.isSuccessCode = r.code.startsWith("2");
|
||||
}
|
||||
Schema responseSchema;
|
||||
if (this.openAPI != null && this.openAPI.getComponents() != null) {
|
||||
@@ -3374,7 +3376,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) {
|
||||
|
||||
@@ -43,10 +43,6 @@ public class HaskellServantCodegen extends DefaultCodegen implements CodegenConf
|
||||
protected String apiVersion = "0.0.1";
|
||||
private static final Pattern LEADING_UNDERSCORE = Pattern.compile("^_+");
|
||||
|
||||
public static final String PROP_SERVE_STATIC = "serveStatic";
|
||||
public static final String PROP_SERVE_STATIC_DESC = "serve will serve files from the directory 'static'.";
|
||||
public static final Boolean PROP_SERVE_STATIC_DEFAULT = Boolean.TRUE;
|
||||
|
||||
/**
|
||||
* Configures the type of generator.
|
||||
*
|
||||
@@ -187,15 +183,6 @@ public class HaskellServantCodegen extends DefaultCodegen implements CodegenConf
|
||||
|
||||
cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
|
||||
cliOptions.add(new CliOption(PROP_SERVE_STATIC, PROP_SERVE_STATIC_DESC).defaultValue(PROP_SERVE_STATIC_DEFAULT.toString()));
|
||||
}
|
||||
|
||||
public void setBooleanProperty(String property, Boolean defaultValue) {
|
||||
if (additionalProperties.containsKey(property)) {
|
||||
additionalProperties.put(property, convertPropertyToBoolean(property));
|
||||
} else {
|
||||
additionalProperties.put(property, defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -205,8 +192,6 @@ public class HaskellServantCodegen extends DefaultCodegen implements CodegenConf
|
||||
if (StringUtils.isEmpty(System.getenv("HASKELL_POST_PROCESS_FILE"))) {
|
||||
LOGGER.info("Hint: Environment variable HASKELL_POST_PROCESS_FILE not defined so the Haskell code may not be properly formatted. To define it, try 'export HASKELL_POST_PROCESS_FILE=\"$HOME/.local/bin/hfmt -w\"' (Linux/Mac)");
|
||||
}
|
||||
|
||||
setBooleanProperty(PROP_SERVE_STATIC, PROP_SERVE_STATIC_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -107,6 +107,7 @@ public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodege
|
||||
supportingFiles.add(new SupportingFile("baseApi.mustache", "", "base.ts"));
|
||||
supportingFiles.add(new SupportingFile("api.mustache", "", "api.ts"));
|
||||
supportingFiles.add(new SupportingFile("configuration.mustache", "", "configuration.ts"));
|
||||
supportingFiles.add(new SupportingFile("custom.d.mustache", "", "custom.d.ts"));
|
||||
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
|
||||
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
|
||||
|
||||
|
||||
@@ -0,0 +1,779 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
* Copyright 2018 SmartBear Software
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import 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.utils.ModelUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
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 final Map<String, String> frameworkToHttpLibMap;
|
||||
|
||||
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");
|
||||
|
||||
|
||||
// clear import mapping (from default generator) as TS does not use it
|
||||
// at the moment
|
||||
importMapping.clear();
|
||||
outputFolder = "generated-code/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");
|
||||
// TODO: allow other types for file e.g. Blob
|
||||
typeMapping.put("File", "any");
|
||||
typeMapping.put("ByteArray", "string");
|
||||
typeMapping.put("UUID", "string");
|
||||
typeMapping.put("Error", "Error");
|
||||
|
||||
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"));
|
||||
|
||||
CliOption frameworkOption = new CliOption(TypeScriptClientCodegen.FRAMEWORK_SWITCH, TypeScriptClientCodegen.FRAMEWORK_SWITCH_DESC);
|
||||
for (String option: TypeScriptClientCodegen.FRAMEWORKS) {
|
||||
// TODO: improve description?
|
||||
frameworkOption.addEnum(option, option);
|
||||
}
|
||||
frameworkOption.defaultValue(FRAMEWORKS[0]);
|
||||
|
||||
cliOptions.add(new CliOption(TypeScriptClientCodegen.PLATFORM_SWITCH, TypeScriptClientCodegen.PLATFORM_SWITCH_DESC));
|
||||
CliOption platformOption = new CliOption(TypeScriptClientCodegen.PLATFORM_SWITCH, TypeScriptClientCodegen.PLATFORM_SWITCH_DESC);
|
||||
for (String option: TypeScriptClientCodegen.PLATFORMS) {
|
||||
// TODO: improve description?
|
||||
platformOption.addEnum(option, option);
|
||||
}
|
||||
platformOption.defaultValue(PLATFORMS[0]);
|
||||
|
||||
cliOptions.add(frameworkOption);
|
||||
|
||||
|
||||
// TODO: gen package.json?
|
||||
|
||||
//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/exception.mustache", "apis", "exception.ts"));
|
||||
// http
|
||||
supportingFiles.add(new SupportingFile("http" + File.separator + "http.mustache", "http", "http.ts"));
|
||||
supportingFiles.add(new SupportingFile("http/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/models_all.mustache", "models", "all.ts"));
|
||||
|
||||
// TODO: add supporting files depending on cli parameter e.g. fetch vs angular
|
||||
supportingFiles.add(new SupportingFile("generators/types/PromiseAPI.mustache", "types", "PromiseAPI.ts"));
|
||||
supportingFiles.add(new SupportingFile("generators/types/ObservableAPI.mustache", "types", "ObservableAPI.ts"));
|
||||
|
||||
// models
|
||||
// TODO: properly set model and api packages
|
||||
this.setModelPackage("");
|
||||
supportingFiles.add(new SupportingFile("model/ObjectSerializer.mustache", "models", "ObjectSerializer.ts"));
|
||||
modelTemplateFiles.put("model/model.mustache", ".ts");
|
||||
|
||||
// api
|
||||
this.setApiPackage("");
|
||||
supportingFiles.add(new SupportingFile("api/middleware.mustache", "", "middleware.ts"));
|
||||
this.supportingFiles.add(new SupportingFile("api/baseapi.mustache", "apis", "baseapi.ts"));
|
||||
this.apiTemplateFiles.put("api/api.mustache", ".ts");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
@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('.', '/'));
|
||||
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;
|
||||
}
|
||||
|
||||
private String getReturnType(List<CodegenResponse> responses) {
|
||||
StringBuilder returnType = new StringBuilder();
|
||||
boolean firstReturnType = true;
|
||||
boolean atLeastOneSuccess = false;
|
||||
boolean addVoid = false;
|
||||
System.out.println(responses);
|
||||
for (CodegenResponse response: responses) {
|
||||
// TODO: we should probably catch an exception here
|
||||
if (response.isSuccessCode) {
|
||||
if (response.dataType != null) {
|
||||
if (!firstReturnType) {
|
||||
returnType.append(" | ");
|
||||
}
|
||||
returnType.append(response.dataType);
|
||||
firstReturnType = false;
|
||||
atLeastOneSuccess = true;
|
||||
} else {
|
||||
addVoid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!atLeastOneSuccess) {
|
||||
return null;
|
||||
} else if (addVoid) {
|
||||
returnType.append(" | void");
|
||||
}
|
||||
|
||||
System.out.println("Return Type: " + returnType);
|
||||
return returnType.toString();
|
||||
}
|
||||
|
||||
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()));
|
||||
}
|
||||
}
|
||||
/* TODO revise the logic below
|
||||
else if (ModelUtils.isDateSchema(p)) {
|
||||
// Handle date enums
|
||||
DateSchema sp = (DateSchema) p;
|
||||
if (sp.getEnum() != null) {
|
||||
return enumValuesToEnumTypeUnion(sp.getEnum(), "string");
|
||||
}
|
||||
} else if (ModelUtils.isDateTimeSchema(p)) {
|
||||
// Handle datetime enums
|
||||
DateTimeSchema sp = (DateTimeSchema) p;
|
||||
if (sp.getEnum() != null) {
|
||||
return enumValuesToEnumTypeUnion(sp.getEnum(), "string");
|
||||
}
|
||||
}*/
|
||||
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(
|
||||
"generators" + File.separator + additionalProperties.get(FRAMEWORK_SWITCH) + ".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"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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)) {
|
||||
// TODO: Change type declaration
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
# {{classname}}
|
||||
|
||||
{{#description}}{{&description}}
|
||||
{{/description}}
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -109,6 +109,7 @@ org.openapitools.codegen.languages.StaticHtml2Generator
|
||||
org.openapitools.codegen.languages.SwiftClientCodegen
|
||||
org.openapitools.codegen.languages.Swift3Codegen
|
||||
org.openapitools.codegen.languages.Swift4Codegen
|
||||
org.openapitools.codegen.languages.TypeScriptClientCodegen
|
||||
org.openapitools.codegen.languages.TypeScriptAngularClientCodegen
|
||||
org.openapitools.codegen.languages.TypeScriptAngularJsClientCodegen
|
||||
org.openapitools.codegen.languages.TypeScriptAureliaClientCodegen
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
# {{{packageName}}}.{{modelPackage}}.{{{classname}}}
|
||||
{{#description}}{{&description}}
|
||||
{{/description}}
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -19,7 +19,6 @@ module {{title}}.API
|
||||
, {{title}}Backend(..)
|
||||
, create{{title}}Client
|
||||
, run{{title}}Server
|
||||
, run{{title}}MiddlewareServer
|
||||
, run{{title}}Client
|
||||
, run{{title}}ClientWithManager
|
||||
, call{{title}}
|
||||
@@ -52,7 +51,6 @@ import GHC.Generics (Generic)
|
||||
import Network.HTTP.Client (Manager, newManager)
|
||||
import Network.HTTP.Client.TLS (tlsManagerSettings)
|
||||
import Network.HTTP.Types.Method (methodOptions)
|
||||
import Network.Wai (Middleware)
|
||||
import qualified Network.Wai.Handler.Warp as Warp
|
||||
import Servant (ServerError, serve)
|
||||
import Servant.API
|
||||
@@ -61,8 +59,7 @@ import Servant.Client (ClientEnv, Scheme (Http), C
|
||||
mkClientEnv, parseBaseUrl)
|
||||
import Servant.Client.Core (baseUrlPort, baseUrlHost)
|
||||
import Servant.Client.Internal.HttpClient (ClientM (..))
|
||||
import Servant.Server (Handler (..)){{#serveStatic}}
|
||||
import Servant.Server.StaticFiles (serveDirectoryFileServer){{/serveStatic}}
|
||||
import Servant.Server (Handler (..))
|
||||
import Web.FormUrlEncoded
|
||||
import Web.HttpApiData
|
||||
|
||||
@@ -132,8 +129,7 @@ formatSeparatedQueryList char = T.intercalate (T.singleton char) . map toQueryPa
|
||||
type {{title}}API
|
||||
= {{#apis}}{{#operations}}{{#operation}}{{& vendorExtensions.x-routeType}} -- '{{operationId}}' route{{#hasMore}}
|
||||
:<|> {{/hasMore}}{{/operation}}{{/operations}}{{#hasMore}}
|
||||
:<|> {{/hasMore}}{{/apis}}{{#serveStatic}}
|
||||
:<|> Raw {{/serveStatic}}
|
||||
:<|> {{/hasMore}}{{/apis}}
|
||||
{{/apiInfo}}
|
||||
|
||||
|
||||
@@ -153,7 +149,7 @@ newtype {{title}}ClientError = {{title}}ClientError ClientError
|
||||
-- | Backend for {{title}}.
|
||||
-- The backend can be used both for the client and the server. The client generated from the {{title}} OpenAPI spec
|
||||
-- is a backend that executes actions by sending HTTP requests (see @create{{title}}Client@). Alternatively, provided
|
||||
-- a backend, the API can be served using @run{{title}}MiddlewareServer@.
|
||||
-- a backend, the API can be served using @run{{title}}Server@.
|
||||
data {{title}}Backend m = {{title}}Backend
|
||||
{ {{#apis}}{{#operations}}{{#operation}}{{operationId}} :: {{& vendorExtensions.x-clientType}}{- ^ {{& notes}} -}{{#hasMore}}
|
||||
, {{/hasMore}}{{/operation}}{{/operations}}{{#hasMore}}
|
||||
@@ -185,8 +181,7 @@ create{{title}}Client = {{title}}Backend{..}
|
||||
where
|
||||
({{#apis}}{{#operations}}{{#operation}}(coerce -> {{operationId}}){{#hasMore}} :<|>
|
||||
{{/hasMore}}{{/operation}}{{/operations}}{{#hasMore}} :<|>
|
||||
{{/hasMore}}{{/apis}}{{#serveStatic}} :<|>
|
||||
_{{/serveStatic}}) = client (Proxy :: Proxy {{title}}API)
|
||||
{{/hasMore}}{{/apis}}) = client (Proxy :: Proxy {{title}}API)
|
||||
|
||||
-- | Run requests in the {{title}}Client monad.
|
||||
run{{title}}Client :: Config -> {{title}}Client a -> ExceptT ClientError IO a
|
||||
@@ -212,31 +207,20 @@ call{{title}} env f = do
|
||||
Right response -> pure response
|
||||
{{/apiInfo}}
|
||||
|
||||
|
||||
{{#apiInfo}}
|
||||
requestMiddlewareId :: Application -> Application
|
||||
requestMiddlewareId a = a
|
||||
|
||||
-- | Run the {{title}} server at the provided host and port.
|
||||
run{{title}}Server
|
||||
:: (MonadIO m, MonadThrow m)
|
||||
=> Config -> {{title}}Backend (ExceptT ServerError IO) -> m ()
|
||||
run{{title}}Server config backend = run{{title}}MiddlewareServer config requestMiddlewareId backend
|
||||
|
||||
-- | Run the {{title}} server at the provided host and port.
|
||||
run{{title}}MiddlewareServer
|
||||
:: (MonadIO m, MonadThrow m)
|
||||
=> Config -> Middleware -> {{title}}Backend (ExceptT ServerError IO) -> m ()
|
||||
run{{title}}MiddlewareServer Config{..} middleware backend = do
|
||||
=> Config -> {{title}}Backend (ExceptT ServerError IO) -> m ()
|
||||
run{{title}}Server Config{..} backend = do
|
||||
url <- parseBaseUrl configUrl
|
||||
let warpSettings = Warp.defaultSettings
|
||||
& Warp.setPort (baseUrlPort url)
|
||||
& Warp.setHost (fromString $ baseUrlHost url)
|
||||
liftIO $ Warp.runSettings warpSettings $ middleware $ serve (Proxy :: Proxy {{title}}API) (serverFromBackend backend)
|
||||
liftIO $ Warp.runSettings warpSettings $ serve (Proxy :: Proxy {{title}}API) (serverFromBackend backend)
|
||||
where
|
||||
serverFromBackend {{title}}Backend{..} =
|
||||
({{#apis}}{{#operations}}{{#operation}}coerce {{operationId}}{{#hasMore}} :<|>
|
||||
{{/hasMore}}{{/operation}}{{/operations}}{{#hasMore}} :<|>
|
||||
{{/hasMore}}{{/apis}}{{#serveStatic}} :<|>
|
||||
serveDirectoryFileServer "static"{{/serveStatic}})
|
||||
{{/hasMore}}{{/apis}})
|
||||
{{/apiInfo}}
|
||||
|
||||
@@ -58,7 +58,7 @@ main = do
|
||||
|
||||
## Creating a Server
|
||||
|
||||
In order to create a server, you must use the `run{{title}}MiddlewareServer` function. However, you unlike the client, in which case you *got* a `{{title}}Backend`
|
||||
In order to create a server, you must use the `run{{title}}Server` function. However, you unlike the client, in which case you *got* a `{{title}}Backend`
|
||||
from the library, you must instead *provide* a `{{title}}Backend`. For example, if you have defined handler functions for all the
|
||||
functions in `{{title}}.Handlers`, you can write:
|
||||
|
||||
@@ -66,24 +66,14 @@ functions in `{{title}}.Handlers`, you can write:
|
||||
{-# LANGUAGE RecordWildCards #-}
|
||||
|
||||
import {{title}}.API
|
||||
-- required dependency: wai
|
||||
import Network.Wai (Middleware)
|
||||
-- required dependency: wai-extra
|
||||
import Network.Wai.Middleware.RequestLogger (logStdout)
|
||||
|
||||
-- A module you wrote yourself, containing all handlers needed for the {{title}}Backend type.
|
||||
import {{title}}.Handlers
|
||||
|
||||
-- If you would like to not use any middlewares you could use run{{title}}Server instead
|
||||
|
||||
-- Combined middlewares
|
||||
requestMiddlewares :: Middleware
|
||||
requestMiddlewares = logStdout
|
||||
|
||||
-- Run a {{title}} server on localhost:8080
|
||||
main :: IO ()
|
||||
main = do
|
||||
let server = {{title}}Backend{..}
|
||||
config = Config "http://localhost:8080/"
|
||||
run{{title}}MiddlewareServer config requestMiddlewares server
|
||||
run{{title}}Server config server
|
||||
```
|
||||
|
||||
@@ -28,7 +28,6 @@ library
|
||||
, servant-client-core
|
||||
, servant-server
|
||||
, servant
|
||||
, wai
|
||||
, warp
|
||||
, transformers
|
||||
, mtl
|
||||
|
||||
@@ -347,19 +347,18 @@ class ApiClient(object):
|
||||
response_type, auth_settings,
|
||||
_return_http_data_only, collection_formats,
|
||||
_preload_content, _request_timeout, _host)
|
||||
|
||||
return self.pool.apply_async(self.__call_api, (resource_path,
|
||||
method, path_params,
|
||||
query_params,
|
||||
header_params, body,
|
||||
post_params, files,
|
||||
response_type,
|
||||
auth_settings,
|
||||
_return_http_data_only,
|
||||
collection_formats,
|
||||
_preload_content,
|
||||
_request_timeout,
|
||||
_host))
|
||||
else:
|
||||
thread = self.pool.apply_async(self.__call_api, (resource_path,
|
||||
method, path_params, query_params,
|
||||
header_params, body,
|
||||
post_params, files,
|
||||
response_type, auth_settings,
|
||||
_return_http_data_only,
|
||||
collection_formats,
|
||||
_preload_content,
|
||||
_request_timeout,
|
||||
_host))
|
||||
return thread
|
||||
|
||||
def request(self, method, url, query_params=None, headers=None,
|
||||
post_params=None, body=None, _preload_content=True,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{{#models}}{{#model}}# {{classname}}
|
||||
|
||||
{{#description}}{{&description}}
|
||||
{{/description}}
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{{#models}}{{#model}}# {{classname}}
|
||||
|
||||
{{#description}}{{&description}}
|
||||
{{/description}}
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Package: {{{packageName}}}
|
||||
Title: R Package Client for {{{appName}}}
|
||||
Version: {{packageVersion}}
|
||||
Authors@R: person("{{#infoName}}{{infoName}}{{/infoName}}{{^infoName}}OpenAPI Generator community{{/infoName}}", email = "{{#infoEmail}}{{infoEmail}}{{/infoEmail}}{{^infoEmail}}team@openapitools.org{{/infoEmail}}", role = c("aut", "cre"))
|
||||
Authors@R: person("OpenAPI Generator community", email = "team@openapitools.org", role = c("aut", "cre"))
|
||||
Description: {{{appDescription}}}{{^appDescription}}R Package Client for {{{appName}}}{{/appDescription}}
|
||||
Depends: R (>= 3.3.3)
|
||||
Encoding: UTF-8
|
||||
License: {{#licenseInfo}}{{licenseInfo}}{{/licenseInfo}}{{^licenseInfo}}Unlicense{{/licenseInfo}}
|
||||
License: Unlicense
|
||||
LazyData: true
|
||||
Suggests: testthat
|
||||
Imports: jsonlite, httr, R6, caTools{{#useRlangExceptionHandling}}, rlang{{/useRlangExceptionHandling}}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{{#models}}{{#model}}# {{packageName}}::{{classname}}
|
||||
|
||||
{{#description}}{{&description}}
|
||||
{{/description}}
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// tslint:disable
|
||||
/// <reference path="./custom.d.ts" />
|
||||
{{>licenseInfo}}
|
||||
|
||||
{{^withSeparateModelsAndApi}}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{{#withSeparateModelsAndApi}}
|
||||
// tslint:disable
|
||||
/// <reference path="{{apiRelativeToRoot}}custom.d.ts" />
|
||||
{{>licenseInfo}}
|
||||
|
||||
import * as globalImportUrl from 'url';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// tslint:disable
|
||||
/// <reference path="./custom.d.ts" />
|
||||
{{>licenseInfo}}
|
||||
|
||||
import { Configuration } from "./configuration";
|
||||
|
||||
1
modules/openapi-generator/src/main/resources/typescript-axios/custom.d.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/typescript-axios/custom.d.mustache
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare module 'url';
|
||||
@@ -1,4 +1,5 @@
|
||||
// tslint:disable
|
||||
/// <reference path="{{modelRelativeToRoot}}custom.d.ts" />
|
||||
{{>licenseInfo}}
|
||||
{{#withSeparateModelsAndApi}}{{#imports}}
|
||||
import { {{class}} } from './{{filename}}';{{/imports}}{{/withSeparateModelsAndApi}}
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
"axios": "^0.18.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.11.5",
|
||||
"typescript": "^3.6.4"
|
||||
"@types/node": "^8.0.9",
|
||||
"typescript": "^2.4"
|
||||
}{{#npmRepository}},{{/npmRepository}}
|
||||
{{#npmRepository}}
|
||||
"publishConfig": {
|
||||
|
||||
1
modules/openapi-generator/src/main/resources/typescript/.gitignore.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/typescript/.gitignore.mustache
vendored
Normal file
@@ -0,0 +1 @@
|
||||
dist
|
||||
1
modules/openapi-generator/src/main/resources/typescript/README.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/typescript/README.mustache
vendored
Normal file
@@ -0,0 +1 @@
|
||||
readme
|
||||
190
modules/openapi-generator/src/main/resources/typescript/api/api.mustache
vendored
Normal file
190
modules/openapi-generator/src/main/resources/typescript/api/api.mustache
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
// 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}}
|
||||
* {{¬es}}
|
||||
{{/notes}}
|
||||
{{#summary}}
|
||||
* {{&summary}}
|
||||
{{/summary}}
|
||||
{{#allParams}}
|
||||
* @param {{paramName}} {{description}}
|
||||
{{/allParams}}
|
||||
*/
|
||||
public {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}options?: Configuration): 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")
|
||||
|
||||
// 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}}
|
||||
localVarFormParams.append('{{baseName}}', {{paramName}}.data, {{paramName}}.name);
|
||||
{{/isFile}}
|
||||
}
|
||||
{{/isListContainer}}
|
||||
{{/formParams}}
|
||||
{{#hasFormParams}}
|
||||
requestContext.setBody(localVarFormParams);
|
||||
{{/hasFormParams}}
|
||||
|
||||
// Body Params
|
||||
{{#bodyParam}}
|
||||
{{^consumes}}
|
||||
requestContext.setHeaderParam("Content-Type", "application/json");
|
||||
{{/consumes}}
|
||||
{{#consumes.0}}
|
||||
requestContext.setHeaderParam("Content-Type", "{{{mediaType}}}");
|
||||
{{/consumes.0}}
|
||||
// TODO: Should this be handled by ObjectSerializer? imo yes => confidential information included in local object should not be sent
|
||||
const needsSerialization = (<any>"{{dataType}}" !== "string") || requestContext.getHeaders()['Content-Type'] === 'application/json';
|
||||
const serializedBody = needsSerialization ? JSON.stringify({{paramName}} || {}) : ({{paramName}}.toString() || ""); // TODO: `toString` call is unnecessary
|
||||
requestContext.setBody(serializedBody);
|
||||
{{/bodyParam}}
|
||||
|
||||
{{#hasAuthMethods}}
|
||||
let authMethod = null;
|
||||
{{/hasAuthMethods}}
|
||||
// Apply auth methods
|
||||
{{#authMethods}}
|
||||
authMethod = config.authMethods["{{name}}"]
|
||||
if (authMethod) {
|
||||
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 {{nicknam}}
|
||||
* @throws ApiException if the response code was not in [200, 299]
|
||||
*/
|
||||
public {{nickname}}(response: ResponseContext): {{#returnType}} {{{returnType}}}{{/returnType}} {{^returnType}} void {{/returnType}} {
|
||||
{{#responses}}
|
||||
if (isCodeInRange("{{code}}", response.httpStatusCode)) {
|
||||
{{#dataType}}
|
||||
const jsonBody = JSON.parse(response.body);
|
||||
const body: {{{dataType}}} = ObjectSerializer.deserialize(jsonBody, "{{{dataType}}}", "{{returnFormat}}") as {{{dataType}}};
|
||||
{{#isSuccessCode}}
|
||||
return body;
|
||||
{{/isSuccessCode}}
|
||||
{{^isSuccessCode}}
|
||||
throw new ApiException<{{{dataType}}}>({{code}}, body);
|
||||
{{/isSuccessCode}}
|
||||
{{/dataType}}
|
||||
{{^dataType}}
|
||||
{{#isSuccessCode}}
|
||||
return;
|
||||
{{/isSuccessCode}}
|
||||
{{^isSuccessCode}}
|
||||
throw new ApiException<string>(response.httpStatusCode, "{{message}}");
|
||||
{{/isSuccessCode}}
|
||||
{{/dataType}}
|
||||
}
|
||||
{{/responses}}
|
||||
|
||||
// Work around for incorrect api specification in petstore.yaml
|
||||
if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) {
|
||||
{{#returnType}}
|
||||
const jsonBody = JSON.parse(response.body);
|
||||
const body: {{{returnType}}} = ObjectSerializer.deserialize(jsonBody, "{{{returnType}}}", "{{returnFormat}}") as {{{returnType}}};
|
||||
return body;
|
||||
{{/returnType}}
|
||||
{{^returnType}}
|
||||
return;
|
||||
{{/returnType}}
|
||||
}
|
||||
let body = response.body || "";
|
||||
throw new ApiException<string>(response.httpStatusCode, "Unknown API Status Code!\nBody: \"" + body + "\"");
|
||||
}
|
||||
|
||||
{{/operation}}
|
||||
}
|
||||
{{/operations}}
|
||||
37
modules/openapi-generator/src/main/resources/typescript/api/baseapi.mustache
vendored
Normal file
37
modules/openapi-generator/src/main/resources/typescript/api/baseapi.mustache
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
14
modules/openapi-generator/src/main/resources/typescript/api/exception.mustache
vendored
Normal file
14
modules/openapi-generator/src/main/resources/typescript/api/exception.mustache
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 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))
|
||||
}
|
||||
}
|
||||
66
modules/openapi-generator/src/main/resources/typescript/api/middleware.mustache
vendored
Normal file
66
modules/openapi-generator/src/main/resources/typescript/api/middleware.mustache
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
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>;
|
||||
}
|
||||
152
modules/openapi-generator/src/main/resources/typescript/auth/auth.mustache
vendored
Normal file
152
modules/openapi-generator/src/main/resources/typescript/auth/auth.mustache
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
import {RequestContext} from '../http/http';
|
||||
// typings for btoa are incorrect
|
||||
//@ts-ignore
|
||||
import * as btoa from "btoa";
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies no authentication.
|
||||
*
|
||||
*/
|
||||
export class NoAuthentication extends SecurityAuthentication {
|
||||
|
||||
public constructor() {
|
||||
super("_no_auth");
|
||||
}
|
||||
|
||||
public applySecurityAuthentication(_context: RequestContext) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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("Authentication", "Basic " + btoa(comb));
|
||||
}
|
||||
}
|
||||
|
||||
// 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}}{{#isHttp}}HttpBasicAuthentication{{/isHttp}}{{#isOAuth}}OAuth2Authentication{{/isOAuth}},
|
||||
{{/authMethods}}
|
||||
}
|
||||
|
||||
export type ApiKeyConfiguration = string;
|
||||
export type HttpBasicConfiguration = { "username": string, "password": string };
|
||||
export type OAuth2Configuration = string;
|
||||
|
||||
export type AuthMethodsConfiguration = { {{#authMethods}}"{{name}}"?:{{#isApiKey}}ApiKeyConfiguration{{/isApiKey}}{{#isHttp}}HttpBasicConfiguration{{/isHttp}}{{#isOAuth}}OAuth2Configuration{{/isOAuth}}, {{/authMethods}} }
|
||||
|
||||
/**
|
||||
* Creates the authentication methods from a swagger description.
|
||||
*
|
||||
*/
|
||||
export function configureAuthMethods(conf: AuthMethodsConfiguration | undefined): AuthMethods {
|
||||
let authMethods: AuthMethods = {
|
||||
}
|
||||
|
||||
if (!conf) {
|
||||
return authMethods;
|
||||
}
|
||||
|
||||
{{#authMethods}}
|
||||
if (conf["{{name}}"]) {
|
||||
{{#isApiKey}}
|
||||
authMethods["{{name}}"] = new APIKeyAuthentication("{{name}}", "{{keyParamName}}", {{#isKeyInQuery}}"query"{{/isKeyInQuery}}{{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{#isKeyInCookie}}"cookie"{{/isKeyInCookie}}, <string> conf["{{name}}"]);
|
||||
{{/isApiKey}}
|
||||
{{#isBasic}}
|
||||
authMethods["{{name}}"] = new HttpBasicAuthentication("{{name}}", config["{{name}}"]["username"], config["{{name}}"]["password"]);
|
||||
{{/isBasic}}
|
||||
{{#isOAuth}}
|
||||
authMethods["{{name}}"] = new OAuth2Authentication("{{name}}");
|
||||
{{/isOAuth}}
|
||||
}
|
||||
|
||||
{{/authMethods}}
|
||||
return authMethods;
|
||||
}
|
||||
67
modules/openapi-generator/src/main/resources/typescript/configuration.mustache
vendored
Normal file
67
modules/openapi-generator/src/main/resources/typescript/configuration.mustache
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
19
modules/openapi-generator/src/main/resources/typescript/generators/fetch-api.mustache
vendored
Normal file
19
modules/openapi-generator/src/main/resources/typescript/generators/fetch-api.mustache
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import * as http from './http/http';
|
||||
import * as auth from './auth/auth';
|
||||
import {Middleware, PromiseMiddleware} from './middleware';
|
||||
import * as models from './models/all';
|
||||
import { Configuration} from './configuration'
|
||||
import * as apis from './types/PromiseAPI';
|
||||
import * as exceptions from './apis/exception';
|
||||
|
||||
export {
|
||||
http,
|
||||
|
||||
auth,
|
||||
Middleware,
|
||||
PromiseMiddleware,
|
||||
models,
|
||||
Configuration,
|
||||
apis,
|
||||
exceptions
|
||||
};
|
||||
19
modules/openapi-generator/src/main/resources/typescript/generators/jquery.mustache
vendored
Normal file
19
modules/openapi-generator/src/main/resources/typescript/generators/jquery.mustache
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import * as http from './http/http';
|
||||
import * as auth from './auth/auth';
|
||||
import {Middleware, PromiseMiddleware} from './middleware';
|
||||
import * as models from './models/all';
|
||||
import { Configuration} from './configuration'
|
||||
import * as apis from './types/PromiseAPI';
|
||||
import * as exceptions from './apis/exception';
|
||||
|
||||
export {
|
||||
http,
|
||||
|
||||
auth,
|
||||
Middleware,
|
||||
PromiseMiddleware,
|
||||
models,
|
||||
Configuration,
|
||||
apis,
|
||||
exceptions
|
||||
};
|
||||
67
modules/openapi-generator/src/main/resources/typescript/generators/types/ObservableAPI.mustache
vendored
Normal file
67
modules/openapi-generator/src/main/resources/typescript/generators/types/ObservableAPI.mustache
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
import { ResponseContext, RequestContext, HttpFile } from '../http/http';
|
||||
import * as models from '../models/all';
|
||||
import { Configuration} from '../configuration'
|
||||
import { Observable, of } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub'{{/useRxJS}};
|
||||
import {mergeMap, map} from {{#useRxJS}}'rxjs/operators'{{/useRxJS}}{{^useRxJS}}'../rxjsStub'{{/useRxJS}};
|
||||
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
import { {{name}} } from '../models/{{name}}';
|
||||
{{/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}}
|
||||
* {{¬es}}
|
||||
{{/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 requestContext = this.requestFactory.{{nickname}}({{#allParams}}{{paramName}}, {{/allParams}}options);
|
||||
|
||||
// build promise chain
|
||||
let middlewarePreObservable = of(requestContext);
|
||||
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}}
|
||||
49
modules/openapi-generator/src/main/resources/typescript/generators/types/PromiseAPI.mustache
vendored
Normal file
49
modules/openapi-generator/src/main/resources/typescript/generators/types/PromiseAPI.mustache
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
import { ResponseContext, RequestContext, HttpFile } from '../http/http';
|
||||
import * as models from '../models/all';
|
||||
import { Configuration} from '../configuration'
|
||||
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
import { {{name}} } from '../models/{{name}}';
|
||||
{{/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}}
|
||||
* {{¬es}}
|
||||
{{/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}}
|
||||
52
modules/openapi-generator/src/main/resources/typescript/git_push.sh.mustache
vendored
Executable file
52
modules/openapi-generator/src/main/resources/typescript/git_push.sh.mustache
vendored
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/sh
|
||||
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
|
||||
#
|
||||
# Usage example: /bin/sh ./git_push.sh wing328 openapi-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'
|
||||
|
||||
151
modules/openapi-generator/src/main/resources/typescript/http/http.mustache
vendored
Normal file
151
modules/openapi-generator/src/main/resources/typescript/http/http.mustache
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
{{#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 a HTTP Method.
|
||||
*/
|
||||
export enum HttpMethod {
|
||||
GET = "GET",
|
||||
HEAD = "HEAD",
|
||||
POST = "POST",
|
||||
PUT = "PUT",
|
||||
DELETE = "DELETE",
|
||||
CONNECT = "CONNECT",
|
||||
OPTIONS = "OPTIONS",
|
||||
TRACE = "TRACE",
|
||||
PATCH = "PATCH"
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a http file which will be uploaded to a server.
|
||||
*/
|
||||
export interface HttpFile {
|
||||
data: {{{fileContentDataType}}};
|
||||
name: string;
|
||||
}
|
||||
|
||||
|
||||
export class HttpException extends Error {
|
||||
public constructor(msg: string) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a HTTP request context
|
||||
*
|
||||
*/
|
||||
export class RequestContext {
|
||||
private headers: { [key: string]: string } = {};
|
||||
private body: string | FormData = "";
|
||||
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
|
||||
* Setting a body on a HTTP GET request is disallowed under HTTP-Spec 1.1. Section
|
||||
* 4.3 and this method throws an HttpException accordingly.
|
||||
*
|
||||
* @param body the body of the request
|
||||
*/
|
||||
public setBody(body: string | FormData) {
|
||||
// HTTP-Spec 1.1 Section 4.3
|
||||
if (this.httpMethod === HttpMethod.GET) {
|
||||
throw new HttpException("Body should not be included in GET-Requests!");
|
||||
}
|
||||
|
||||
// TODO: other http methods
|
||||
|
||||
// post is fine either formData or string
|
||||
this.body = body;
|
||||
|
||||
}
|
||||
|
||||
public getHttpMethod(): HttpMethod {
|
||||
return this.httpMethod;
|
||||
}
|
||||
|
||||
public getHeaders(): { [key: string]: string } {
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
public getBody(): string | FormData {
|
||||
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 class ResponseContext {
|
||||
|
||||
public constructor(public httpStatusCode: number,
|
||||
public headers: { [key: string]: string }, public body: string) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export interface HttpLibrary {
|
||||
send(request: RequestContext): Observable<ResponseContext>;
|
||||
}
|
||||
35
modules/openapi-generator/src/main/resources/typescript/http/isomorphic-fetch.mustache
vendored
Normal file
35
modules/openapi-generator/src/main/resources/typescript/http/isomorphic-fetch.mustache
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
declare var fetch: any;
|
||||
|
||||
import {HttpLibrary, RequestContext, ResponseContext} from './http';
|
||||
import * as e6p from 'es6-promise'
|
||||
import { from, Observable } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub'{{/useRxJS}};
|
||||
e6p.polyfill();
|
||||
import 'isomorphic-fetch';
|
||||
|
||||
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(),
|
||||
credentials: "same-origin"
|
||||
}).then((resp: any) => {
|
||||
// hack
|
||||
let headers = (resp.headers as any)._headers;
|
||||
for (let key in headers) {
|
||||
headers[key] = (headers[key] as Array<string>).join("; ");
|
||||
}
|
||||
|
||||
return resp.text().then((body: string) => {
|
||||
return new ResponseContext(resp.status, headers, body)
|
||||
});
|
||||
});
|
||||
|
||||
return from<Promise<ResponseContext>>(resultPromise);
|
||||
|
||||
}
|
||||
}
|
||||
79
modules/openapi-generator/src/main/resources/typescript/http/jquery.mustache
vendored
Normal file
79
modules/openapi-generator/src/main/resources/typescript/http/jquery.mustache
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
import {HttpLibrary, RequestContext, ResponseContext, HttpException} from './http';
|
||||
import * as e6p from 'es6-promise'
|
||||
import { from, Observable } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub'{{/useRxJS}};
|
||||
e6p.polyfill();
|
||||
import * as $ from 'jquery';
|
||||
{{#platforms}}
|
||||
{{#node}}
|
||||
import * as FormData from "form-data";
|
||||
{{/node}}
|
||||
{{/platforms}}
|
||||
|
||||
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 (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.constructor.name == "FormData") {
|
||||
requestOptions.contentType = false;
|
||||
}
|
||||
const sentRequest = $.ajax(requestOptions);
|
||||
|
||||
const resultPromise = new Promise<ResponseContext>((resolve, reject) => {
|
||||
sentRequest.done((resp, _, jqXHR) => {
|
||||
const headers = this.getResponseHeaders(jqXHR)
|
||||
const result = new ResponseContext(jqXHR.status, headers, JSON.stringify(resp));
|
||||
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
|
||||
}
|
||||
}
|
||||
57
modules/openapi-generator/src/main/resources/typescript/http/servers.mustache
vendored
Normal file
57
modules/openapi-generator/src/main/resources/typescript/http/servers.mustache
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
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> {
|
||||
|
||||
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>) {
|
||||
for (const key in variableConfiguration) {
|
||||
const val = variableConfiguration[key]
|
||||
// We know that val isn't undefined here - hopefully
|
||||
if (val !== undefined) {
|
||||
this.variableConfiguration[key] = val as T[Extract<keyof T, string>];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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].toString());
|
||||
}
|
||||
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}}
|
||||
11
modules/openapi-generator/src/main/resources/typescript/licenseInfo.mustache
vendored
Normal file
11
modules/openapi-generator/src/main/resources/typescript/licenseInfo.mustache
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* {{{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.
|
||||
*/
|
||||
165
modules/openapi-generator/src/main/resources/typescript/model/ObjectSerializer.mustache
vendored
Normal file
165
modules/openapi-generator/src/main/resources/typescript/model/ObjectSerializer.mustache
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
{{#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"
|
||||
];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
78
modules/openapi-generator/src/main/resources/typescript/model/model.mustache
vendored
Normal file
78
modules/openapi-generator/src/main/resources/typescript/model/model.mustache
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
{{>licenseInfo}}
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{#tsImports}}
|
||||
import { {{classname}} } from './{{filename}}';
|
||||
{{/tsImports}}
|
||||
|
||||
{{#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}}
|
||||
5
modules/openapi-generator/src/main/resources/typescript/model/models_all.mustache
vendored
Normal file
5
modules/openapi-generator/src/main/resources/typescript/model/models_all.mustache
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
export * from './{{name}}'
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
51
modules/openapi-generator/src/main/resources/typescript/package.mustache
vendored
Normal file
51
modules/openapi-generator/src/main/resources/typescript/package.mustache
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "{{npmName}}",
|
||||
"version": "1.0.0",
|
||||
"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}}
|
||||
"isomorphic-fetch": "^2.2.1",
|
||||
"@types/isomorphic-fetch": "0.0.34",
|
||||
{{/fetch-api}}
|
||||
{{#jquery}}
|
||||
"@types/jquery": "^3.3.29",
|
||||
"jquery": "^3.4.1",
|
||||
{{/jquery}}
|
||||
{{/frameworks}}
|
||||
{{#platforms}}
|
||||
{{#node}}
|
||||
"@types/node": "*",
|
||||
"form-data": "^2.5.0",
|
||||
{{/node}}
|
||||
{{/platforms}}
|
||||
{{#useRxJS}}
|
||||
"rxjs": "^6.4.0",
|
||||
{{/useRxJS}}
|
||||
"btoa": "^1.2.1",
|
||||
"es6-promise": "^4.2.4",
|
||||
"url-parse": "^1.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^2.9.2"
|
||||
}{{#npmRepository}},{{/npmRepository}}
|
||||
{{#npmRepository}}
|
||||
"publishConfig":{
|
||||
"registry":"{{npmRepository}}"
|
||||
}
|
||||
{{/npmRepository}}
|
||||
}
|
||||
27
modules/openapi-generator/src/main/resources/typescript/rxjsStub.mustache
vendored
Normal file
27
modules/openapi-generator/src/main/resources/typescript/rxjsStub.mustache
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
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;
|
||||
}
|
||||
29
modules/openapi-generator/src/main/resources/typescript/tsconfig.mustache
vendored
Normal file
29
modules/openapi-generator/src/main/resources/typescript/tsconfig.mustache
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"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,
|
||||
"lib": [ "es6", "dom" ]
|
||||
},
|
||||
"exclude": [
|
||||
"dist",
|
||||
"node_modules"
|
||||
],
|
||||
"filesGlob": [
|
||||
"./**/*.ts",
|
||||
]
|
||||
|
||||
}
|
||||
28
modules/openapi-generator/src/main/resources/typescript/util.mustache
vendored
Normal file
28
modules/openapi-generator/src/main/resources/typescript/util.mustache
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ package org.openapitools.codegen.options;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.languages.HaskellServantCodegen;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -45,7 +44,6 @@ public class HaskellServantOptionsProvider implements OptionsProvider {
|
||||
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
|
||||
.put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE)
|
||||
.put(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, PREPEND_FORM_OR_BODY_PARAMETERS_VALUE)
|
||||
.put(HaskellServantCodegen.PROP_SERVE_STATIC, HaskellServantCodegen.PROP_SERVE_STATIC_DEFAULT.toString())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
16
pom.xml
16
pom.xml
@@ -10,7 +10,7 @@
|
||||
<packaging>pom</packaging>
|
||||
<name>openapi-generator-project</name>
|
||||
<!-- RELEASE_VERSION -->
|
||||
<version>4.2.0</version>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<!-- /RELEASE_VERSION -->
|
||||
<url>https://github.com/openapitools/openapi-generator</url>
|
||||
<scm>
|
||||
@@ -798,6 +798,18 @@
|
||||
<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/client/petstore/typescript/tests/default</module>
|
||||
</modules>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>typescript-fetch-client-tests-default</id>
|
||||
<activation>
|
||||
@@ -1059,6 +1071,8 @@
|
||||
<module>samples/client/petstore/python-asyncio</module>
|
||||
<module>samples/client/petstore/python-tornado</module>
|
||||
<module>samples/openapi3/client/petstore/python</module>
|
||||
<module>samples/client/petstore/typescript/builds/default</module>
|
||||
<module>samples/client/petstore/typescript/tests/default</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>
|
||||
|
||||
@@ -5,7 +5,7 @@ Authors@R: person("OpenAPI Generator community", email = "team@openapitools.org"
|
||||
Description: This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
Depends: R (>= 3.3.3)
|
||||
Encoding: UTF-8
|
||||
License: Apache-2.0
|
||||
License: Unlicense
|
||||
LazyData: true
|
||||
Suggests: testthat
|
||||
Imports: jsonlite, httr, R6, caTools
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# petstore::Category
|
||||
|
||||
A category for a pet
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# petstore::ModelApiResponse
|
||||
|
||||
Describes the result of uploading an image resource
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# petstore::Order
|
||||
|
||||
An order for a pets from the pet store
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# petstore::Pet
|
||||
|
||||
A pet for sale in the pet store
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# petstore::Tag
|
||||
|
||||
A tag for a pet
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# petstore::User
|
||||
|
||||
A User who is purchasing from the pet store
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Org.OpenAPITools.Model.ClassModel
|
||||
Model for testing model with \"_class\" property
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Org.OpenAPITools.Model.File
|
||||
Must be named `File` for test.
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Org.OpenAPITools.Model.Model200Response
|
||||
Model for testing model name starting with number
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Org.OpenAPITools.Model.Name
|
||||
Model for testing model name same as property name
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Org.OpenAPITools.Model.Return
|
||||
Model for testing reserved words
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Org.OpenAPITools.Model.ClassModel
|
||||
Model for testing model with \"_class\" property
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Org.OpenAPITools.Model.File
|
||||
Must be named `File` for test.
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Org.OpenAPITools.Model.Model200Response
|
||||
Model for testing model name starting with number
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Org.OpenAPITools.Model.Name
|
||||
Model for testing model name same as property name
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Org.OpenAPITools.Model.Return
|
||||
Model for testing reserved words
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# ClassModel
|
||||
|
||||
Model for testing model with \"_class\" property
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# Model200Response
|
||||
|
||||
Model for testing model name starting with number
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# ModelReturn
|
||||
|
||||
Model for testing reserved words
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# Name
|
||||
|
||||
Model for testing model name same as property name
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# ClassModel
|
||||
|
||||
Model for testing model with \"_class\" property
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# Model200Response
|
||||
|
||||
Model for testing model name starting with number
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# ModelReturn
|
||||
|
||||
Model for testing reserved words
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# Name
|
||||
|
||||
Model for testing model name same as property name
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# ClassModel
|
||||
|
||||
Model for testing model with \"_class\" property
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# Model200Response
|
||||
|
||||
Model for testing model name starting with number
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# ModelReturn
|
||||
|
||||
Model for testing reserved words
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# Name
|
||||
|
||||
Model for testing model name same as property name
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# ClassModel
|
||||
|
||||
Model for testing model with \"_class\" property
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# Model200Response
|
||||
|
||||
Model for testing model name starting with number
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
# ModelReturn
|
||||
|
||||
Model for testing reserved words
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user