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

This commit is contained in:
William Cheng 2018-08-03 00:10:34 +08:00
commit be2a0170b7
628 changed files with 13796 additions and 7660 deletions

2
.gitignore vendored
View File

@ -99,6 +99,8 @@ samples/client/petstore/silex/SwaggerServer/venodr/
samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/cache/
samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/logs/
#PHP-laravel
samples/server/petstore/php-laravel/node_modules
# Perl
samples/client/petstore/perl/deep_module_test/

View File

@ -920,7 +920,7 @@
</repository>
</repositories>
<properties>
<swagger-parser-version>2.0.1</swagger-parser-version>
<swagger-parser-version>2.0.2-OpenAPITools.org-1</swagger-parser-version>
<swagger-core-version>2.0.1</swagger-core-version>
<scala-version>2.11.1</scala-version>
<felix-version>3.3.0</felix-version>

View File

@ -976,7 +976,7 @@
</repository>
</repositories>
<properties>
<swagger-parser-version>2.0.1</swagger-parser-version>
<swagger-parser-version>2.0.2-OpenAPITools.org-1</swagger-parser-version>
<swagger-core-version>2.0.1</swagger-core-version>
<scala-version>2.11.1</scala-version>
<felix-version>3.3.0</felix-version>

View File

@ -948,7 +948,7 @@
</repository>
</repositories>
<properties>
<swagger-parser-version>2.0.1</swagger-parser-version>
<swagger-parser-version>2.0.2-OpenAPITools.org-1</swagger-parser-version>
<swagger-core-version>2.0.1</swagger-core-version>
<scala-version>2.11.1</scala-version>
<felix-version>3.3.0</felix-version>

View File

@ -928,7 +928,7 @@
</repository>
</repositories>
<properties>
<swagger-parser-version>2.0.1</swagger-parser-version>
<swagger-parser-version>2.0.2-OpenAPITools.org-1</swagger-parser-version>
<swagger-core-version>2.0.1</swagger-core-version>
<scala-version>2.11.1</scala-version>
<felix-version>3.3.0</felix-version>

View File

@ -14,8 +14,9 @@ COPY ./LICENSE ${GEN_DIR}
COPY ./google_checkstyle.xml ${GEN_DIR}
# Modules are copied individually here to allow for caching of docker layers between major.minor versions
# NOTE: openapi-generator-online is not included here
COPY ./modules/openapi-generator-gradle-plugin ${GEN_DIR}/modules/openapi-generator-gradle-plugin
COPY ./modules/openapi-generator-maven-plugin ${GEN_DIR}/modules/openapi-generator-maven-plugin
COPY ./modules/openapi-generator-online ${GEN_DIR}/modules/openapi-generator-online
COPY ./modules/openapi-generator-cli ${GEN_DIR}/modules/openapi-generator-cli
COPY ./modules/openapi-generator ${GEN_DIR}/modules/openapi-generator
COPY ./pom.xml ${GEN_DIR}

View File

@ -317,6 +317,20 @@ Once built, `run-in-docker.sh` will act as an executable for openapi-generator-c
-g go -o /gen/out/go-petstore -DpackageName=petstore # generates go client, outputs locally to ./out/go-petstore
```
##### Troubleshooting
If an error like this occurs, just execute the **mvn clean install -U** command:
> org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test (default-test) on project openapi-generator: A type incompatibility occurred while executing org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test: java.lang.ExceptionInInitializerError cannot be cast to java.io.IOException
```sh
./run-in-docker.sh mvn clean install -U
```
> Failed to execute goal org.fortasoft:gradle-maven-plugin:1.0.8:invoke (default) on project openapi-generator-gradle-plugin-mvn-wrapper: org.gradle.tooling.BuildException: Could not execute build using Gradle distribution 'https://services.gradle.org/distributions/gradle-4.7-bin.zip'
Right now: no solution for this one :|
#### Run Docker in Vagrant
Prerequisite: install [Vagrant](https://www.vagrantup.com/downloads.html) and [VirtualBox](https://www.virtualbox.org/wiki/Downloads).
```sh
@ -545,6 +559,7 @@ Here is a list of template creators:
* Ada: @stcarrez
* C# ASP.NET5: @jimschubert
* C# NancyFX: @mstefaniuk
* C++ (Qt5 QHttpEngine): @etherealjoy
* C++ Pistache: @sebymiano
* C++ Restbed: @stkrwork
* Erlang Server: @galaxie
@ -560,6 +575,7 @@ Here is a list of template creators:
* JAX-RS CXF (CDI): @nickcmaynard
* JAX-RS RestEasy (JBoss EAP): @jfiala
* Kotlin: @jimschubert
* PHP Laravel: @renepardon
* PHP Lumen: @abcsun
* PHP Slim: @jfastnacht
* PHP Symfony: @ksm2

View File

@ -0,0 +1,42 @@
#!/bin/bash
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
# Make sure that the working directory is the root dir
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "${SCRIPT_DIR}/../"
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
# Make sure that we are regenerating the sample by removing any existing target directory
TARGET_DIR="$SCRIPT_DIR/../../samples/server/petstore/php-laravel"
if [ -d "$TARGET_DIR" ]; then
rm -rf $TARGET_DIR
fi
executable="$SCRIPT_DIR/../../modules/openapi-generator-cli/target/openapi-generator-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t $SCRIPT_DIR/../../modules/openapi-generator/src/main/resources/php-laravel -i $SCRIPT_DIR/../../modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php-laravel -o $TARGET_DIR $@"
java $JAVA_OPTS -jar $executable $ags

View File

@ -0,0 +1,32 @@
#!/bin/sh
SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
if [ ! -f "$executable" ]
then
mvn -B clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/php-laravel -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g php-laravel -o samples/server/petstore/php-laravel $@"
java $JAVA_OPTS -jar $executable $ags

View File

@ -25,8 +25,10 @@ then
mvn -B clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/rust-server -i modules/openapi-generator/src/test/resources/2_0/rust-server/petstore-with-fake-endpoints-models-for-testing.yaml -g rust-server -o samples/server/petstore/rust-server -DpackageName=petstore_api --additional-properties hideGenerationTimestamp=true $@"
for spec_path in modules/openapi-generator/src/test/resources/2_0/rust-server/* ; do
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
spec=$(basename "$spec_path" | sed 's/.yaml//')
ags="generate -t modules/openapi-generator/src/main/resources/rust-server -i $spec_path -g rust-server -o samples/server/petstore/rust-server/output/$spec -DpackageName=$spec --additional-properties hideGenerationTimestamp=true $@"
java $JAVA_OPTS -jar $executable $ags
java $JAVA_OPTS -jar $executable $ags
done

View File

@ -36,6 +36,9 @@ echo "IMPORTANT: this script works on Mac only"
echo "Release preparation: replacing $FROM with $TO in different files"
declare -a files=("modules/openapi-generator-maven-plugin/README.md"
"modules/openapi-generator-maven-plugin/examples/java-client.xml"
"modules/openapi-generator-maven-plugin/examples/non-java-invalid-spec.xml"
"modules/openapi-generator-maven-plugin/examples/non-java.xml"
"modules/openapi-generator-gradle-plugin/README.adoc"
"modules/openapi-generator-gradle-plugin/samples/local-spec/gradle.properties"
"modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle"

View File

@ -17,6 +17,17 @@ Version `3.2.0` is a minor version of OpenAPI-Generator, in comparison to `3.1.x
The default value of some options might change.
Projects relying on generated code might need to be adapted.
==== Validate spec on generation by default
The default is to validate the spec during generation. If the spec has errors,
they will appear as errors or warnings to the user. This prevent generation of the project.
If you want to switch back to the `3.1.x` behavior you can use:
* Set the `validateSpec` option to `false` if you are using the Maven or Gradle plugin
* Use the command line option `--skip-validate-spec` if you are using the CLI
==== Model (all languages)
In `CodegenModel` and in `CodegenOperation` we use now our own class `org.openapitools.codegen.CodegenDiscriminator` instead of `io.swagger.v3.oas.models.media.Discriminator`.

View File

@ -12,7 +12,7 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.1.1-SNAPSHOT</version>
<version>3.1.2</version>
<executions>
<execution>
<goals>
@ -20,7 +20,7 @@
</goals>
<configuration>
<!-- specify the swagger yaml -->
<inputSpec>swagger.yaml</inputSpec>
<inputSpec>${project.basedir}/swagger.yaml</inputSpec>
<!-- target to generate java client code -->
<generatorName>java</generatorName>
@ -39,13 +39,22 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- dependencies are needed for the client being generated -->
<dependency>
<groupId>org.openapitools</groupId>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations-version}</version>
</dependency>
@ -55,13 +64,8 @@
<!-- HTTP client: jersey-client -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
@ -69,6 +73,11 @@
<artifactId>jersey-media-multipart</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey-version}</version>
</dependency>
<!-- JSON processing: jackson -->
<dependency>
@ -96,7 +105,7 @@
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson-version}</version>
</dependency>
<!-- Joda time: if you use it -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
@ -107,19 +116,19 @@
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${jodatime-version}</version>
</dependency>
</dependency>
<!-- Base64 encoding that works in both JVM and Android -->
<dependency>
<groupId>com.brsanthu</groupId>
<artifactId>migbase64</artifactId>
<version>2.2</version>
</dependency>
</dependency>
</dependencies>
<properties>
<swagger-annotations-version>1.5.8</swagger-annotations-version>
<jersey-version>2.22.2</jersey-version>
<jersey-version>2.27</jersey-version>
<jackson-version>2.8.9</jackson-version>
<jodatime-version>2.7</jodatime-version>
<maven-plugin-version>1.0.0</maven-plugin-version>

View File

@ -12,7 +12,7 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.1.1-SNAPSHOT</version>
<version>3.1.2</version>
<executions>
<execution>
<goals>
@ -20,7 +20,7 @@
</goals>
<configuration>
<validateSpec>false</validateSpec>
<inputSpec>petstore-v3.0-invalid.yaml</inputSpec>
<inputSpec>${project.basedir}/petstore-v3.0-invalid.yaml</inputSpec>
<generatorName>aspnetcore</generatorName>
<configOptions>
<additional-properties>optionalProjectFile=true</additional-properties>

View File

@ -12,14 +12,14 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.1.1-SNAPSHOT</version>
<version>3.1.2</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>swagger.yaml</inputSpec>
<inputSpec>${project.basedir}/swagger.yaml</inputSpec>
<generatorName>aspnetcore</generatorName>
<configOptions>
<additional-properties>optionalProjectFile=true</additional-properties>

View File

@ -204,9 +204,9 @@
<version>${swagger-core-version}</version>
</dependency>
<dependency>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser</artifactId>
<version>${swagger-parser-version}</version>
<groupId>org.openapitools.swagger.parser</groupId>
<artifactId>swagger-parser</artifactId>
<version>${swagger-parser-version}</version>
</dependency>
<dependency>
<groupId>com.samskivert</groupId>

View File

@ -257,4 +257,8 @@ public class CodegenConstants {
public static final String DOCEXTENSION = "docExtension";
public static final String DOCEXTENSION_DESC = "The extension of the generated documentation files, defaults to markdown, .md";
public static final String DATABASE_ADAPTER = "databaseAdapter";
public static final String DATABASE_ADAPTER_DESC = "The adapter for database (e.g. mysql, sqlite). Default: sqlite";
}

View File

@ -4423,7 +4423,11 @@ public class DefaultCodegen implements CodegenConfig {
}
if (StringUtils.isEmpty(bodyParameterName)) {
codegenParameter.baseName = mostInnerItem.complexType;
if(StringUtils.isEmpty(mostInnerItem.complexType)) {
codegenParameter.baseName = "request_body";
} else {
codegenParameter.baseName = mostInnerItem.complexType;
}
} else {
codegenParameter.baseName = bodyParameterName;
}

View File

@ -95,7 +95,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
/**
* Programmatically disable the output of .openapi-generator/VERSION, .openapi-generator-ignore,
* or other metadata files used by Swagger Codegen.
* or other metadata files used by OpenAPI Generator.
*
* @param generateMetadata true: enable outputs, false: disable outputs
*/
@ -193,8 +193,14 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
URL url = URLPathUtils.getServerURL(openAPI);
contextPath = config.escapeText(url.getPath());
basePath = config.escapeText(URLPathUtils.getHost(openAPI));
basePathWithoutHost = contextPath; // for backward compatibility
basePath = config.escapeText(URLPathUtils.getHost(openAPI));
if ("/".equals(basePath.substring(basePath.length() - 1))) {
// remove trailing "/"
// https://host.example.com/ => https://host.example.com
basePath = basePath.substring(0, basePath.length() - 1);
}
}
private void configureOpenAPIInfo() {

View File

@ -536,7 +536,7 @@ public class CodegenConfigurator implements Serializable {
if (this.isValidateSpec()) {
StringBuilder sb = new StringBuilder();
sb.append("There were issues with the specification. The option can be disabled by passing false to skipValidateSpec (Maven/Gradle) or --skip-validate-spec (CLI).");
sb.append("There were issues with the specification. The option can be disabled via validateSpec (Maven/Gradle) or --skip-validate-spec (CLI).");
sb.append(System.lineSeparator());
SpecValidationException ex = new SpecValidationException(sb.toString());
ex.setErrors(validationMessages);

View File

@ -0,0 +1,680 @@
/*
* 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 java.util.*;
import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Strings;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.utils.ModelUtils;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.responses.ApiResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractApexCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractApexCodegen.class);
protected Boolean serializableModel = false;
public AbstractApexCodegen() {
super();
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getName() {
return "apex";
}
@Override
public String getHelp() {
return "Generates an Apex API client library.";
}
@Override
public void processOpts() {
super.processOpts();
}
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@Override
public String sanitizeName(String name) {
name = super.sanitizeName(name);
if (name.contains("__")) { // Preventing namespacing
name.replaceAll("__", "_");
}
if (name.matches("^\\d.*")) { // Prevent named credentials with leading number
name.replaceAll("^\\d.*", "");
}
return name;
}
@Override
public String toVarName(String name) {
// sanitize name
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
if (name.toLowerCase().matches("^_*class$")) {
return "propertyClass";
}
if ("_".equals(name)) {
name = "_u";
}
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$")) {
if (isReservedWord(name)) {
name = escapeReservedWord(name);
}
return name;
}
if (startsWithTwoUppercaseLetters(name)) {
name = name.substring(0, 2).toLowerCase() + name.substring(2);
}
// camelize (lower first character) the variable name
// pet_id => petId
name = camelize(name, true);
// for reserved word or word starting with number, append _
if (isReservedWord(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
return name;
}
private boolean startsWithTwoUppercaseLetters(String name) {
boolean startsWithTwoUppercaseLetters = false;
if (name.length() > 1) {
startsWithTwoUppercaseLetters = name.substring(0, 2).equals(name.substring(0, 2).toUpperCase());
}
return startsWithTwoUppercaseLetters;
}
@Override
public String toParamName(String name) {
// to avoid conflicts with 'callback' parameter for async call
if ("callback".equals(name)) {
return "paramCallback";
}
// should be the same as variable name
return toVarName(name);
}
@Override
public String toModelName(final String name) {
final String sanitizedName = sanitizeName(name);
String nameWithPrefixSuffix = sanitizedName;
if (!StringUtils.isEmpty(modelNamePrefix)) {
// add '_' so that model name can be camelized correctly
nameWithPrefixSuffix = modelNamePrefix + "_" + nameWithPrefixSuffix;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
// add '_' so that model name can be camelized correctly
nameWithPrefixSuffix = nameWithPrefixSuffix + "_" + modelNameSuffix;
}
// camelize the model name
// phone_number => PhoneNumber
final String camelizedName = camelize(nameWithPrefixSuffix);
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(camelizedName)) {
final String modelName = "Model" + camelizedName;
LOGGER.warn(camelizedName + " (reserved word) cannot be used as model name. Renamed to " + modelName);
return modelName;
}
// model name starts with number
if (camelizedName.matches("^\\d.*")) {
final String modelName = "Model" + camelizedName; // 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;
}
return camelizedName;
}
@Override
public String toModelFilename(String name) {
// should be the same as the model name
return toModelName(name);
}
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Schema inner = ap.getItems();
if (inner == null) {
LOGGER.warn(ap.getName() + "(array property) does not have a proper inner type defined");
// TODO maybe better defaulting to StringProperty than returning null
return null;
}
return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
if (inner == null) {
LOGGER.warn(p.getName() + "(map property) does not have a proper inner type defined");
// TODO maybe better defaulting to StringProperty than returning null
return null;
}
return getSchemaType(p) + "<String, " + getTypeDeclaration(inner) + ">";
}
return super.getTypeDeclaration(p);
}
@Override
public String getAlias(String name) {
if (typeAliases != null && typeAliases.containsKey(name)) {
return typeAliases.get(name);
}
return name;
}
@Override
public String toDefaultValue(Schema p) {
if (ModelUtils.isArraySchema(p)) {
final ArraySchema ap = (ArraySchema) p;
final String pattern = "new ArrayList<%s>()";
if (ap.getItems() == null) {
return null;
}
return String.format(pattern, getTypeDeclaration(ap.getItems()));
} else if (ModelUtils.isMapSchema(p)) {
final MapSchema ap = (MapSchema) p;
final String pattern = "new HashMap<%s>()";
if (ap.getAdditionalProperties() == null) {
return null;
}
return String.format(pattern, String.format("String, %s", getTypeDeclaration((Schema) ap.getAdditionalProperties())));
} else if (ModelUtils.isLongSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString() + "l";
}
return "null";
} else if (ModelUtils.isIntegerSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
return "null";
} else if (ModelUtils.isFloatSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString() + "f";
}
return "null";
} else if (ModelUtils.isDoubleSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString() + "d";
}
return "null";
} else if (ModelUtils.isBooleanSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
return "null";
} else if (ModelUtils.isStringSchema(p)) {
if (p.getDefault() != null) {
String _default = (String) p.getDefault();
if (p.getEnum() == null) {
return "\"" + escapeText(_default) + "\"";
} else {
// convert to enum var name later in postProcessModels
return _default;
}
}
return "null";
}
return super.toDefaultValue(p);
}
@Override
public void setParameterExampleValue(CodegenParameter p) {
if (Boolean.TRUE.equals(p.isLong)) {
p.example = "2147483648L";
} else if (Boolean.TRUE.equals(p.isFile)) {
p.example = "Blob.valueOf('Sample text file\\nContents')";
} else if (Boolean.TRUE.equals(p.isDate)) {
p.example = "Date.newInstance(1960, 2, 17)";
} else if (Boolean.TRUE.equals(p.isDateTime)) {
p.example = "Datetime.newInstanceGmt(2013, 11, 12, 3, 3, 3)";
} else if (Boolean.TRUE.equals(p.isListContainer)) {
if (p.items != null && p.items.example != null) {
p.example = "new " + p.dataType + "{" + p.items.example + "}";
}
} else if (Boolean.TRUE.equals(p.isMapContainer)) {
if (p.items != null && p.items.example != null) {
p.example = "new " + p.dataType + "{" + p.items.example + "}";
}
} else if (Boolean.TRUE.equals(p.isString)) {
p.example = "'" + p.example + "'";
} else if ("".equals(p.example) || p.example == null && p.dataType != "Object") {
// Get an example object from the generated model
if (!isReservedWord(p.dataType.toLowerCase())) {
p.example = p.dataType + ".getExample()";
}
} else {
p.example = "''";
}
}
@Override
public String toExampleValue(Schema p) {
if (p == null) {
return "";
}
Object obj = p.getExample();
String example = obj == null ? "" : obj.toString();
if (ModelUtils.isArraySchema(p)) {
example = "new " + getTypeDeclaration(p) + "{" + toExampleValue(
((ArraySchema) p).getItems()) + "}";
} else if (ModelUtils.isBooleanSchema(p)) {
example = String.valueOf(!"false".equals(example));
} else if (ModelUtils.isByteArraySchema(p)) {
if (example.isEmpty()) {
example = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu";
}
((ByteArraySchema) p).setExample(example);
example = "EncodingUtil.base64Decode('" + example + "')";
} else if (ModelUtils.isDateSchema(p)) {
if (example.matches("^\\d{4}(-\\d{2}){2}")) {
example = example.substring(0, 10).replaceAll("-0?", ", ");
} else if (example.isEmpty()) {
example = "2000, 1, 23";
} else {
LOGGER.warn(String.format("The example provided for property '%s' is not a valid RFC3339 date. Defaulting to '2000-01-23'. [%s]", p
.getName(), example));
example = "2000, 1, 23";
}
example = "Date.newInstance(" + example + ")";
} else if (ModelUtils.isDateTimeSchema(p)) {
if (example.matches("^\\d{4}([-T:]\\d{2}){5}.+")) {
example = example.substring(0, 19).replaceAll("[-T:]0?", ", ");
} else if (example.isEmpty()) {
example = "2000, 1, 23, 4, 56, 7";
} else {
LOGGER.warn(String.format("The example provided for property '%s' is not a valid RFC3339 datetime. Defaulting to '2000-01-23T04-56-07Z'. [%s]", p
.getName(), example));
example = "2000, 1, 23, 4, 56, 7";
}
example = "Datetime.newInstanceGmt(" + example + ")";
} else if (ModelUtils.isNumberSchema(p)) {
example = example.replaceAll("[^-0-9.]", "");
example = example.isEmpty() ? "1.3579" : example;
} else if (ModelUtils.isFileSchema(p)) {
if (example.isEmpty()) {
example = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu";
p.setExample(example);
}
example = "EncodingUtil.base64Decode(" + example + ")";
} else if (ModelUtils.isEmailSchema(p)) {
if (example.isEmpty()) {
example = "example@example.com";
p.setExample(example);
}
example = "'" + example + "'";
} else if (ModelUtils.isLongSchema(p)) {
example = example.isEmpty() ? "123456789L" : example + "L";
} else if (ModelUtils.isMapSchema(p)) {
example = "new " + getTypeDeclaration(p) + "{'key'=>" + toExampleValue((Schema) p.getAdditionalProperties()) + "}";
} else if (ModelUtils.isPasswordSchema(p)) {
example = example.isEmpty() ? "password123" : escapeText(example);
p.setExample(example);
example = "'" + example + "'";
} else if (ModelUtils.isStringSchema(p)) {
List<String> enums = p.getEnum();
if (enums != null && example.isEmpty()) {
example = enums.get(0);
p.setExample(example);
} else if (example.isEmpty()) {
example = "";
} else {
example = escapeText(example);
p.setExample(example);
}
example = "'" + example + "'";
} else if (ModelUtils.isUUIDSchema(p)) {
example = example.isEmpty()
? "'046b6c7f-0b8a-43b9-b35d-6489e6daee91'"
: "'" + escapeText(example) + "'";
} else if (ModelUtils.isIntegerSchema(p)) {
example = example.matches("^-?\\d+$") ? example : "0";
} else if (ModelUtils.isObjectSchema(p)) {
example = example.isEmpty() ? "null" : example;
} else {
example = getTypeDeclaration(p) + ".getExample()";
}
return example;
}
@Override
public String getSchemaType(Schema p) {
String schemaType = super.getSchemaType(p);
schemaType = getAlias(schemaType);
// don't apply renaming on types from the typeMapping
if (typeMapping.containsKey(schemaType)) {
return typeMapping.get(schemaType);
}
if (null == schemaType) {
LOGGER.error("No Type defined for Property " + p);
}
return toModelName(schemaType);
}
@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException("Empty method/operation name (operationId) not allowed");
}
operationId = camelize(sanitizeName(operationId), true);
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(operationId)) {
String newOperationId = camelize("call_" + operationId, true);
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + newOperationId);
return newOperationId;
}
return operationId;
}
@Override
public CodegenModel fromModel(String name, Schema model, Map<String, Schema> allDefinitions) {
CodegenModel cm = super.fromModel(name, model, allDefinitions);
// TODO Check enum model handling
if (cm.interfaces == null) {
cm.interfaces = new ArrayList<String>();
}
Boolean hasDefaultValues = false;
// for (de)serializing properties renamed for Apex (e.g. reserved words)
List<Map<String, String>> propertyMappings = new ArrayList<>();
for (CodegenProperty p : cm.allVars) {
hasDefaultValues |= p.defaultValue != null;
if (!p.baseName.equals(p.name)) {
Map<String, String> mapping = new HashMap<>();
mapping.put("externalName", p.baseName);
mapping.put("internalName", p.name);
propertyMappings.add(mapping);
}
}
cm.vendorExtensions.put("hasPropertyMappings", !propertyMappings.isEmpty());
cm.vendorExtensions.put("hasDefaultValues", hasDefaultValues);
cm.vendorExtensions.put("propertyMappings", propertyMappings);
if (!propertyMappings.isEmpty()) {
cm.interfaces.add("OAS.MappedProperties");
}
return cm;
}
@Override
public void postProcessParameter(CodegenParameter parameter) {
if (parameter.isBodyParam && parameter.isListContainer) {
// items of array bodyParams are being nested an extra level too deep for some reason
parameter.items = parameter.items.items;
setParameterExampleValue(parameter);
}
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
return postProcessModelsEnum(objs);
}
/* the following function is not used anywhere in this class so we'll remove it later
private static String getAccept(Operation operation) {
String accepts = null;
String defaultContentType = "application/json";
if (operation.getProduces() != null && !operation.getProduces().isEmpty()) {
StringBuilder sb = new StringBuilder();
for (String produces : operation.getProduces()) {
if (defaultContentType.equalsIgnoreCase(produces)) {
accepts = defaultContentType;
break;
} else {
if (sb.length() > 0) {
sb.append(",");
}
sb.append(produces);
}
}
if (accepts == null) {
accepts = sb.toString();
}
} else {
accepts = defaultContentType;
}
return accepts;
}*/
@Override
protected boolean needToImport(String type) {
return super.needToImport(type) && type.indexOf(".") < 0;
}
@Override
public String toEnumName(CodegenProperty property) {
return sanitizeName(camelize(property.name)) + "Enum";
}
@Override
public String toEnumVarName(String value, String datatype) {
if (value.length() == 0) {
return "EMPTY";
}
// for symbol, e.g. $, #
if (getSymbolName(value) != null) {
return getSymbolName(value).toUpperCase();
}
// number
if ("Integer".equals(datatype) || "Long".equals(datatype) ||
"Float".equals(datatype) || "Double".equals(datatype)) {
String varName = "NUMBER_" + value;
varName = varName.replaceAll("-", "MINUS_");
varName = varName.replaceAll("\\+", "PLUS_");
varName = varName.replaceAll("\\.", "_DOT_");
return varName;
}
// string
String var = value.replaceAll("\\W+", "_").toUpperCase();
if (var.matches("\\d.*")) {
return "_" + var;
} else {
return var;
}
}
@Override
public String toEnumValue(String value, String datatype) {
if ("Integer".equals(datatype) || "Double".equals(datatype)) {
return value;
} else if ("Long".equals(datatype)) {
// add l to number, e.g. 2048 => 2048l
return value + "l";
} else if ("Float".equals(datatype)) {
// add f to number, e.g. 3.14 => 3.14f
return value + "f";
} else {
return "\"" + escapeText(value) + "\"";
}
}
@Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Schema> definitions, OpenAPI openAPI) {
CodegenOperation op = super.fromOperation(
path, httpMethod, operation, definitions, openAPI);
if (op.getHasExamples()) {
// prepare examples for Apex test classes
ApiResponse apiResponse = findMethodResponse(operation.getResponses());
final Schema responseSchema = ModelUtils.getSchemaFromResponse(apiResponse);
String deserializedExample = toExampleValue(responseSchema);
for (Map<String, String> example : op.examples) {
example.put("example", escapeText(example.get("example")));
example.put("deserializedExample", deserializedExample);
}
}
return op;
}
private static CodegenModel reconcileInlineEnums(CodegenModel codegenModel, CodegenModel parentCodegenModel) {
// This generator uses inline classes to define enums, which breaks when
// dealing with models that have subTypes. To clean this up, we will analyze
// the parent and child models, look for enums that match, and remove
// them from the child models and leave them in the parent.
// Because the child models extend the parents, the enums will be available via the parent.
// Only bother with reconciliation if the parent model has enums.
if (!parentCodegenModel.hasEnums) {
return codegenModel;
}
// Get the properties for the parent and child models
final List<CodegenProperty> parentModelCodegenProperties = parentCodegenModel.vars;
List<CodegenProperty> codegenProperties = codegenModel.vars;
// Iterate over all of the parent model properties
boolean removedChildEnum = false;
for (CodegenProperty parentModelCodegenPropery : parentModelCodegenProperties) {
// Look for enums
if (parentModelCodegenPropery.isEnum) {
// Now that we have found an enum in the parent class,
// and search the child class for the same enum.
Iterator<CodegenProperty> iterator = codegenProperties.iterator();
while (iterator.hasNext()) {
CodegenProperty codegenProperty = iterator.next();
if (codegenProperty.isEnum && codegenProperty.equals(parentModelCodegenPropery)) {
// We found an enum in the child class that is
// a duplicate of the one in the parent, so remove it.
iterator.remove();
removedChildEnum = true;
}
}
}
}
if (removedChildEnum) {
// If we removed an entry from this model's vars, we need to ensure hasMore is updated
int count = 0, numVars = codegenProperties.size();
for (CodegenProperty codegenProperty : codegenProperties) {
count += 1;
codegenProperty.hasMore = (count < numVars) ? true : false;
}
codegenModel.vars = codegenProperties;
}
return codegenModel;
}
private static String sanitizePackageName(String packageName) {
packageName = packageName.trim(); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
packageName = packageName.replaceAll("[^a-zA-Z0-9_\\.]", "_");
if (Strings.isNullOrEmpty(packageName)) {
return "invalidPackageName";
}
return packageName;
}
public void setSerializableModel(Boolean serializableModel) {
this.serializableModel = serializableModel;
}
private String sanitizePath(String p) {
//prefer replace a ", instead of a fuLL URL encode for readability
return p.replaceAll("\"", "%22");
}
public String toRegularExpression(String pattern) {
return escapeText(pattern);
}
public boolean convertPropertyToBoolean(String propertyKey) {
boolean booleanValue = false;
if (additionalProperties.containsKey(propertyKey)) {
booleanValue = Boolean.valueOf(additionalProperties.get(propertyKey).toString());
}
return booleanValue;
}
public void writePropertyBack(String propertyKey, boolean value) {
additionalProperties.put(propertyKey, value);
}
@Override
public String sanitizeTag(String tag) {
return camelize(sanitizeName(tag));
}
@Override
public String toModelTestFilename(String name) {
return toModelName(name) + "Test";
}
}

View File

@ -603,6 +603,12 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
operationId = "call_" + operationId;
}
// operationId starts with a number
if (operationId.matches("^\\d.*")) {
LOGGER.warn(operationId + " (starting with a number) cannot be used as method name. Renamed to " + camelize(sanitizeName("call_" + operationId)));
operationId = "call_" + operationId;
}
return camelize(sanitizeName(operationId));
}

View File

@ -128,6 +128,38 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
);
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String toApiName(String type) {
return sanitizeName(modelNamePrefix + Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api");
}
@Override
public String toModelName(String type) {
if (type == null) {
LOGGER.warn("Model name can't be null. Default to 'UnknownModel'.");
type = "UnknownModel";
}
if (typeMapping.keySet().contains(type) || typeMapping.values().contains(type)
|| importMapping.values().contains(type) || defaultIncludes.contains(type)
|| languageSpecificPrimitives.contains(type)) {
return type;
} else {
return sanitizeName(modelNamePrefix + Character.toUpperCase(type.charAt(0)) + type.substring(1));
}
}
@Override
public String toVarName(String name) {
if (typeMapping.keySet().contains(name) || typeMapping.values().contains(name)

View File

@ -145,7 +145,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = sanitizeName(name);
@ -267,10 +267,10 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
// the type.
String openAPIType = getSchemaType(p);
String ref = p.get$ref();
if(ref != null && !ref.isEmpty()) {
if (ref != null && !ref.isEmpty()) {
String tryRefV2 = "#/definitions/" + openAPIType;
String tryRefV3 = "#/components/schemas/" + openAPIType;
if(ref.equals(tryRefV2) || ref.equals(tryRefV3)) {
if (ref.equals(tryRefV2) || ref.equals(tryRefV3)) {
return toModelName(openAPIType);
}
}
@ -296,7 +296,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
String ref = p.get$ref();
String type = null;
if(ref != null && !ref.isEmpty()) {
if (ref != null && !ref.isEmpty()) {
type = openAPIType;
} else if (typeMapping.containsKey(openAPIType)) {
type = typeMapping.get(openAPIType);
@ -314,7 +314,13 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(sanitizedOperationId)) {
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to "
+ camelize("call_" + operationId));
+ camelize("call_" + sanitizedOperationId));
sanitizedOperationId = "call_" + sanitizedOperationId;
}
// operationId starts with a number
if (sanitizedOperationId.matches("^\\d.*")) {
LOGGER.warn(operationId + " (starting with a number) cannot be used as method name. Renamed to " + camelize("call_" + sanitizedOperationId));
sanitizedOperationId = "call_" + sanitizedOperationId;
}
@ -564,8 +570,10 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
enumName = enumName.replaceFirst("^_", "");
enumName = enumName.replaceFirst("_$", "");
if (isReservedWord(enumName) || enumName.matches("\\d.*")) { // reserved word or starts with number
if (isReservedWord(enumName)) { // reserved word
return escapeReservedWord(enumName);
} else if (enumName.matches("\\d.*")) { // starts with a number
return "_" + enumName;
} else {
return enumName;
}

View File

@ -884,6 +884,12 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
return newOperationId;
}
// operationId starts with a number
if (operationId.matches("^\\d.*")) {
LOGGER.warn(operationId + " (starting with a number) cannot be used as method sname. Renamed to " + camelize("call_" + operationId), true);
operationId = camelize("call_" + operationId, true);
}
return operationId;
}

View File

@ -18,7 +18,6 @@
package org.openapitools.codegen.languages;
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 org.apache.commons.lang3.StringUtils;
@ -157,7 +156,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
@Override
public String toVarName(String name) {
// sanitize name
name = sanitizeName(name);
name = sanitizeName(name, "\\W-[\\$]");
if ("_".equals(name)) {
name = "_u";

View File

@ -17,65 +17,43 @@
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.BooleanSchema;
import io.swagger.v3.oas.models.media.ByteArraySchema;
import io.swagger.v3.oas.models.media.EmailSchema;
import io.swagger.v3.oas.models.media.FileSchema;
import io.swagger.v3.oas.models.media.PasswordSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.responses.ApiResponse;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.utils.ModelUtils;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.info.*;
import io.swagger.v3.oas.models.OpenAPI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.*;
public class ApexClientCodegen extends AbstractJavaCodegen {
public class ApexClientCodegen extends AbstractApexCodegen {
private static final String CLASS_PREFIX = "classPrefix";
private static final String API_VERSION = "apiVersion";
private static final String BUILD_METHOD = "buildMethod";
private static final String NAMED_CREDENTIAL = "namedCredential";
private static final Logger LOGGER = LoggerFactory.getLogger(ApexClientCodegen.class);
private String classPrefix = "Swag";
private String apiVersion = "39.0";
private String classPrefix = "OAS";
private String apiVersion = "42.0";
private String buildMethod = "sfdx";
private String namedCredential = classPrefix;
private String srcPath = "force-app/main/default/";
private String sfdxConfigPath = "config/";
private HashMap<String, Object> primitiveDefaults = new HashMap<String, Object>();
public ApexClientCodegen() {
super();
importMapping.clear();
testFolder = sourceFolder = srcPath;
embeddedTemplateDir = templateDir = "apex";
outputFolder = "generated-code" + File.separator + "apex";
apiPackage = "classes";
modelPackage = "classes";
modelPackage = apiPackage = srcPath + "classes";
testPackage = "force-app.main.default.classes";
modelNamePrefix = classPrefix;
dateLibrary = "";
apiTemplateFiles.put("api.mustache", ".cls");
apiTemplateFiles.put("cls-meta.mustache", ".cls-meta.xml");
@ -91,12 +69,12 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
cliOptions.add(CliOption.newString(BUILD_METHOD, "The build method for this package."));
cliOptions.add(CliOption.newString(NAMED_CREDENTIAL, "The named credential name for the HTTP callouts"));
supportingFiles.add(new SupportingFile("Swagger.cls", srcPath + "classes", "Swagger.cls"));
supportingFiles.add(new SupportingFile("cls-meta.mustache", srcPath + "classes", "Swagger.cls-meta.xml"));
supportingFiles.add(new SupportingFile("SwaggerTest.cls", srcPath + "classes", "SwaggerTest.cls"));
supportingFiles.add(new SupportingFile("cls-meta.mustache", srcPath + "classes", "SwaggerTest.cls-meta.xml"));
supportingFiles.add(new SupportingFile("SwaggerResponseMock.cls", srcPath + "classes", "SwaggerResponseMock.cls"));
supportingFiles.add(new SupportingFile("cls-meta.mustache", srcPath + "classes", "SwaggerResponseMock.cls-meta.xml"));
supportingFiles.add(new SupportingFile("OAS.cls", srcPath + "classes", "OAS.cls"));
supportingFiles.add(new SupportingFile("cls-meta.mustache", srcPath + "classes", "OAS.cls-meta.xml"));
supportingFiles.add(new SupportingFile("OASTest.cls", srcPath + "classes", "OASTest.cls"));
supportingFiles.add(new SupportingFile("cls-meta.mustache", srcPath + "classes", "OASTest.cls-meta.xml"));
supportingFiles.add(new SupportingFile("OASResponseMock.cls", srcPath + "classes", "OASResponseMock.cls"));
supportingFiles.add(new SupportingFile("cls-meta.mustache", srcPath + "classes", "OASResponseMock.cls-meta.xml"));
typeMapping.put("BigDecimal", "Double");
typeMapping.put("binary", "String");
@ -109,14 +87,15 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
typeMapping.put("short", "Integer");
typeMapping.put("UUID", "String");
// https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_reserved_words.htm
setReservedWordsLowerCase(
Arrays.asList("abstract", "activate", "and", "any", "array", "as", "asc", "autonomous",
"begin", "bigdecimal", "blob", "break", "bulk", "by", "byte", "case", "cast",
"catch", "char", "class", "collect", "commit", "const", "continue",
"convertcurrency", "date", "decimal", "default", "delete", "desc", "do", "else",
"convertcurrency", "currency", "date", "datetime", "decimal", "default", "delete", "desc", "do", "else",
"end", "enum", "exception", "exit", "export", "extends", "false", "final",
"finally", "float", "for", "from", "future", "global", "goto", "group", "having",
"hint", "if", "implements", "import", "inner", "insert", "instanceof", "int",
"hint", "if", "implements", "import", "in", "inner", "insert", "instanceof", "int",
"interface", "into", "join", "last_90_days", "last_month", "last_n_days",
"last_week", "like", "limit", "list", "long", "loop", "map", "merge", "new",
"next_90_days", "next_month", "next_n_days", "next_week", "not", "null", "nulls",
@ -124,7 +103,7 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
"pragma", "private", "protected", "public", "retrieve", "return", "returning",
"rollback", "savepoint", "search", "select", "set", "short", "sort", "stat",
"static", "super", "switch", "synchronized", "system", "testmethod", "then", "this",
"this_month", "this_week", "throw", "today", "tolabel", "tomorrow", "transaction",
"this_month", "this_week", "throw", "time", "today", "tolabel", "tomorrow", "transaction",
"trigger", "true", "try", "type", "undelete", "update", "upsert", "using",
"virtual", "webservice", "when", "where", "while", "yesterday"
));
@ -133,6 +112,17 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
Arrays.asList("Blob", "Boolean", "Date", "Datetime", "Decimal", "Double", "ID",
"Integer", "Long", "Object", "String", "Time"
));
primitiveDefaults.put("Boolean", true);
primitiveDefaults.put("Decimal", 1);
primitiveDefaults.put("Double", 1);
primitiveDefaults.put("Integer", 1);
primitiveDefaults.put("Long", 1);
primitiveDefaults.put("String", "");
instantiationTypes.put("array", "List");
instantiationTypes.put("map", "Map");
}
@Override
@ -162,6 +152,48 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
postProcessOpts();
}
@Override
public void preprocessOpenAPI(OpenAPI openAPI) {
Info info = openAPI.getInfo();
String calloutLabel = info.getTitle();
additionalProperties.put("calloutLabel", calloutLabel);
String sanitized = sanitizeName(calloutLabel);
additionalProperties.put("calloutName", sanitized);
supportingFiles.add(new SupportingFile("namedCredential.mustache", srcPath + "/namedCredentials",
sanitized + ".namedCredential-meta.xml"
));
if (additionalProperties.get(BUILD_METHOD).equals("sfdx")) {
generateSfdxSupportingFiles();
} else if (additionalProperties.get(BUILD_METHOD).equals("ant")) {
generateAntSupportingFiles();
}
}
@Override
public String escapeQuotationMark(String input) {
return input.replace("'", "\\'");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String escapeText(String input) {
if (input == null) {
return input;
}
return input.replace("'", "\\'").replace("\n", "\\n").replace("\r", "\\r").replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String toApiName(String name) {
return camelize(classPrefix + super.toApiName(name));
}
@Override
public String escapeReservedWord(String name) {
// Identifiers must start with a letter
@ -191,16 +223,19 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
} else if (ModelUtils.isBooleanSchema(p)) {
// true => "true", false => "false", null => "null"
out = String.valueOf(((BooleanSchema) p).getDefault());
} else if (ModelUtils.isLongSchema(p)) { // long
out = p.getDefault() == null ? out : p.getDefault().toString() + "L";
} else if (ModelUtils.isLongSchema(p)) {
Long def = (Long) p.getDefault();
out = def == null ? out : def.toString() + "L";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
String s = inner == null ? "Object" : getTypeDeclaration(inner);
out = String.format("new Map<String, %s>()", s);
} else if (ModelUtils.isStringSchema(p)) {
String def = (String) p.getDefault();
if (def != null) {
out = p.getEnum() == null ? String.format("'%s'", escapeText(def)) : def;
if (p.getDefault() != null) {
String def = p.getDefault().toString();
if (def != null) {
out = p.getEnum() == null ? String.format("'%s'", escapeText(def)) : def;
}
}
} else {
out = super.toDefaultValue(p);
@ -210,256 +245,10 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
return "null".equals(out) ? null : out;
}
@Override
public void setParameterExampleValue(CodegenParameter p) {
String example;
if (p.defaultValue == null) {
example = p.example;
} else {
example = p.defaultValue;
}
String type = p.baseType;
if (type == null) {
type = p.dataType;
}
if (Boolean.TRUE.equals(p.isInteger)) {
if (example == null) {
example = "56";
}
} else if (Boolean.TRUE.equals(p.isLong)) {
if (example == null) {
example = "2147483648L";
}
} else if (Boolean.TRUE.equals(p.isDouble)
|| Boolean.TRUE.equals(p.isFloat)
|| Boolean.TRUE.equals(p.isNumber)) {
if (example == null) {
example = "3.4";
}
} else if (Boolean.TRUE.equals(p.isBoolean)) {
if (Boolean.parseBoolean(p.example)) {
p.example = "1";
} else {
p.example = "0";
}
} else if (Boolean.TRUE.equals(p.isFile) || Boolean.TRUE.equals(p.isBinary)) {
example = "Blob.valueOf('Sample text file\\nContents')";
} else if (Boolean.TRUE.equals(p.isByteArray)) {
if (example == null) {
example = "YmFzZSA2NCBkYXRh";
}
example = "\"" + escapeText(example) + "\"";
} else if (Boolean.TRUE.equals(p.isDate)) {
if (example == null) {
example = "1960, 2, 17";
}
example = "Date.newInstance(" + escapeText(p.example) + ")";
} else if (Boolean.TRUE.equals(p.isDateTime)) {
if (example == null) {
example = "2013, 11, 12, 3, 3, 3";
}
example = "Datetime.newInstanceGmt(" + escapeText(p.example) + ")";
} else if (Boolean.TRUE.equals(p.isString)) {
if (example == null) {
example = p.paramName + "_example";
}
example = "\'" + escapeText(example) + "\'";
} else if (!languageSpecificPrimitives.contains(type)) {
// type is a model class, e.g. User
example = type + ".getExample()";
}
// container
if (Boolean.TRUE.equals(p.isListContainer)) {
example = setPropertyExampleValue(p.items);
example = "new " + p.dataType + "{" + example + "}";
} else if (Boolean.TRUE.equals(p.isMapContainer)) {
example = setPropertyExampleValue(p.items);
example = "new " + p.dataType + "{" + example + "}";
} else if (example == null) {
example = "null";
}
p.example = example;
}
protected String setPropertyExampleValue(CodegenProperty p) {
String example;
if (p == null) {
return "null";
}
if (p.defaultValue == null) {
example = p.example;
} else {
example = p.defaultValue;
}
String type = p.baseType;
if (type == null) {
type = p.dataType;
}
if (Boolean.TRUE.equals(p.isInteger)) {
if (example == null) {
example = "56";
}
} else if (Boolean.TRUE.equals(p.isLong)) {
if (example == null) {
example = "2147483648L";
}
} else if (Boolean.TRUE.equals(p.isDouble)
|| Boolean.TRUE.equals(p.isFloat)
|| Boolean.TRUE.equals(p.isNumber)) {
if (example == null) {
example = "3.4";
}
} else if (Boolean.TRUE.equals(p.isBoolean)) {
if (example == null) {
example = "true";
}
} else if (Boolean.TRUE.equals(p.isFile) || Boolean.TRUE.equals(p.isBinary)) {
if (example == null) {
example = "Blob.valueOf('Sample text file\\nContents')";
}
example = escapeText(example);
} else if (Boolean.TRUE.equals(p.isDate)) {
if (example == null) {
example = "1960, 2, 17";
}
example = "Date.newInstance(" + escapeText(p.example) + ")";
} else if (Boolean.TRUE.equals(p.isDateTime)) {
if (example == null) {
example = "2013, 11, 12, 3, 3, 3";
}
example = "Datetime.newInstanceGmt(" + escapeText(p.example) + ")";
} else if (Boolean.TRUE.equals(p.isString)) {
if (example == null) {
example = p.name + "_example";
}
example = "\'" + escapeText(example) + "\'";
} else if (!languageSpecificPrimitives.contains(type)) {
// type is a model class, e.g. User
example = type + ".getExample()";
}
return example;
}
@Override
public CodegenModel fromModel(String name, Schema model, Map<String, Schema> allDefinitions) {
CodegenModel cm = super.fromModel(name, model, allDefinitions);
if (cm.interfaces == null) {
cm.interfaces = new ArrayList<String>();
}
Boolean hasDefaultValues = false;
// for (de)serializing properties renamed for Apex (e.g. reserved words)
List<Map<String, String>> propertyMappings = new ArrayList<>();
for (CodegenProperty p : cm.allVars) {
hasDefaultValues |= p.defaultValue != null;
if (!p.baseName.equals(p.name)) {
Map<String, String> mapping = new HashMap<>();
mapping.put("externalName", p.baseName);
mapping.put("internalName", p.name);
propertyMappings.add(mapping);
}
}
cm.vendorExtensions.put("hasPropertyMappings", !propertyMappings.isEmpty());
cm.vendorExtensions.put("hasDefaultValues", hasDefaultValues);
cm.vendorExtensions.put("propertyMappings", propertyMappings);
if (!propertyMappings.isEmpty()) {
cm.interfaces.add("Swagger.MappedProperties");
}
return cm;
}
/* the following workaround is no longer needed
@Override
public void postProcessParameter(CodegenParameter parameter) {
if (parameter.isBodyParam && parameter.isListContainer) {
// items of array bodyParams are being nested an extra level too deep for some reason
parameter.items = parameter.items.items;
setParameterExampleValue(parameter);
}
}
*/
@Override
public void preprocessOpenAPI(OpenAPI openAPI) {
Info info = openAPI.getInfo();
String calloutLabel = info.getTitle();
additionalProperties.put("calloutLabel", calloutLabel);
String sanitized = sanitizeName(calloutLabel);
additionalProperties.put("calloutName", sanitized);
supportingFiles.add(new SupportingFile("namedCredential.mustache", srcPath + "/namedCredentials",
sanitized + ".namedCredential"
));
if (additionalProperties.get(BUILD_METHOD).equals("sfdx")) {
generateSfdxSupportingFiles();
} else if (additionalProperties.get(BUILD_METHOD).equals("ant")) {
generateAntSupportingFiles();
}
}
@Override
public CodegenOperation fromOperation(String path,
String httpMethod,
Operation operation,
Map<String, Schema> definitions,
OpenAPI openAPI) {
Boolean hasFormParams = false;
// comment out the following as there's no consume/produce in OAS3.0
// we can move the logic below to postProcessOperations if needed
/*
// only support serialization into JSON and urlencoded forms for now
operation.setConsumes(
Collections.singletonList(hasFormParameter(operation)
? "application/x-www-form-urlencoded"
: "application/json"));
// only support deserialization from JSON for now
operation.setProduces(Collections.singletonList("application/json"));
*/
CodegenOperation op = super.fromOperation(path, httpMethod, operation, definitions, openAPI);
if (op.getHasExamples()) {
// prepare examples for Apex test classes
ApiResponse responseProperty = findMethodResponse(operation.getResponses());
String deserializedExample = toExampleValue(ModelUtils.getSchemaFromResponse(responseProperty));
for (Map<String, String> example : op.examples) {
example.put("example", escapeText(example.get("example")));
example.put("deserializedExample", deserializedExample);
}
}
return op;
}
@Override
public String escapeQuotationMark(String input) {
return input.replace("'", "\\'");
}
public void setBuildMethod(String buildMethod) {
if (buildMethod.equals("ant")) {
this.srcPath = "deploy/";
} else {
this.srcPath = "src/";
}
testFolder = sourceFolder = srcPath;
this.buildMethod = buildMethod;
}
@ -494,114 +283,6 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
));
}
@Override
public String escapeText(String input) {
if (input == null) {
return input;
}
return input.replace("'", "\\'").replace("\n", "\\n").replace("\r", "\\r");
}
@Override
public String toModelTestFilename(String name) {
return toModelName(name) + "Test";
}
@Override
public String toExampleValue(Schema p) {
if (p == null) {
return "";
}
Object obj = p.getExample();
String example = obj == null ? "" : obj.toString();
if (ModelUtils.isArraySchema(p)) { // array
example = "new " + getTypeDeclaration(p) + "{" + toExampleValue(
((ArraySchema) p).getItems()) + "}";
} else if (ModelUtils.isBooleanSchema(p)) {
example = String.valueOf(!"false".equals(example));
} else if (ModelUtils.isByteArraySchema(p)) { // byte array
if (example.isEmpty()) {
example = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu";
}
((ByteArraySchema) p).setExample(example);
example = "EncodingUtil.base64Decode('" + example + "')";
} else if (ModelUtils.isDateSchema(p)) { // date
if (example.matches("^\\d{4}(-\\d{2}){2}")) {
example = example.substring(0, 10).replaceAll("-0?", ", ");
} else if (example.isEmpty()) {
example = "2000, 1, 23";
} else {
LOGGER.warn(String.format("The example provided for property '%s' is not a valid RFC3339 date. Defaulting to '2000-01-23'. [%s]", p
.getName(), example));
example = "2000, 1, 23";
}
example = "Date.newInstance(" + example + ")";
} else if (ModelUtils.isDateTimeSchema(p)) { // datetime
if (example.matches("^\\d{4}([-T:]\\d{2}){5}.+")) {
example = example.substring(0, 19).replaceAll("[-T:]0?", ", ");
} else if (example.isEmpty()) {
example = "2000, 1, 23, 4, 56, 7";
} else {
LOGGER.warn(String.format("The example provided for property '%s' is not a valid RFC3339 datetime. Defaulting to '2000-01-23T04-56-07Z'. [%s]", p
.getName(), example));
example = "2000, 1, 23, 4, 56, 7";
}
example = "Datetime.newInstanceGmt(" + example + ")";
} else if (ModelUtils.isNumberSchema(p)) { // number
example = example.replaceAll("[^-0-9.]", "");
example = example.isEmpty() ? "1.3579" : example;
} else if (ModelUtils.isFileSchema(p)) { // file
if (example.isEmpty()) {
example = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu";
((FileSchema) p).setExample(example);
}
example = "EncodingUtil.base64Decode(" + example + ")";
} else if (ModelUtils.isEmailSchema(p)) { // email
if (example.isEmpty()) {
example = "example@example.com";
((EmailSchema) p).setExample(example);
}
example = "'" + example + "'";
} else if (ModelUtils.isLongSchema(p)) { // long
example = example.isEmpty() ? "123456789L" : example + "L";
} else if (ModelUtils.isMapSchema(p)) { // map
example = "new " + getTypeDeclaration(p) + "{'key'=>" + toExampleValue(
(Schema) p.getAdditionalProperties()) + "}";
} else if (ModelUtils.isObjectSchema(p)) { // object
example = example.isEmpty() ? "null" : example;
} else if (ModelUtils.isPasswordSchema(p)) { // password
example = example.isEmpty() ? "password123" : escapeText(example);
((PasswordSchema) p).setExample(example);
example = "'" + example + "'";
} else if (!StringUtils.isEmpty(p.get$ref())) {
example = getTypeDeclaration(p) + ".getExample()";
} else if (ModelUtils.isUUIDSchema(p)) {
example = example.isEmpty()
? "'046b6c7f-0b8a-43b9-b35d-6489e6daee91'"
: "'" + escapeText(example) + "'";
} else if (ModelUtils.isStringSchema(p)) { // string
List<String> enums = p.getEnum();
if (enums != null && example.isEmpty()) {
example = enums.get(0);
p.setExample(example);
} else if (example.isEmpty()) {
example = "aeiou";
} else {
example = escapeText(example);
p.setExample(example);
}
example = "'" + example + "'";
}
return example;
}
@Override
public String toApiName(String name) {
return camelize(classPrefix + super.toApiName(name));
}
@Override
public void updateCodegenPropertyEnum(CodegenProperty var) {
super.updateCodegenPropertyEnum(var);
@ -612,21 +293,6 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
}
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getName() {
return "apex";
}
@Override
public String getHelp() {
return "Generates an Apex API client library (beta).";
}
private void generateAntSupportingFiles() {
supportingFiles.add(new SupportingFile("package.mustache", "deploy", "package.xml"));
@ -638,11 +304,17 @@ public class ApexClientCodegen extends AbstractJavaCodegen {
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
writeOptional(outputFolder, new SupportingFile("README_ant.mustache", "README.md"));
}
private void generateSfdxSupportingFiles() {
supportingFiles.add(new SupportingFile("sfdx.mustache", "", "sfdx-oss-manifest.json"));
supportingFiles.add(new SupportingFile("sfdx-project-scratch-def.json", sfdxConfigPath, "project-scratch-def.json"));
supportingFiles.add(new SupportingFile("sfdx-project.json.mustache", "sfdx-project.json"));
writeOptional(outputFolder, new SupportingFile("README_sfdx.mustache", "README.md"));
}
}

View File

@ -129,18 +129,6 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
}
}
/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle
* escaping those terms here. This logic is only called if a variable
* matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
}
@Override
public String toModelImport(String name) {
if (importMapping.containsKey(name)) {
@ -392,33 +380,6 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
return toModelName(type);
}
@Override
public String toModelName(String type) {
if (typeMapping.keySet().contains(type) || typeMapping.values().contains(type)
|| importMapping.values().contains(type) || defaultIncludes.contains(type)
|| languageSpecificPrimitives.contains(type)) {
return type;
} else {
return Character.toUpperCase(type.charAt(0)) + type.substring(1);
}
}
@Override
public String toApiName(String type) {
return Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String getTypeDeclaration(String str) {
return toModelName(str);

View File

@ -251,20 +251,6 @@ public class CppQt5ClientCodegen extends AbstractCppCodegen implements CodegenCo
return "#include \"" + folder + toModelName(name) + ".h\"";
}
/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
* those terms here. This logic is only called if a variable matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
/**
* Location to write model files. You can use the modelPackage() as defined when the class is
* instantiated
@ -378,25 +364,6 @@ public class CppQt5ClientCodegen extends AbstractCppCodegen implements CodegenCo
return toModelName(type);
}
@Override
public String toModelName(String type) {
if (type == null) {
LOGGER.warn("Model name can't be null. Default to 'UnknownModel'.");
type = "UnknownModel";
}
if (typeMapping.keySet().contains(type) ||
typeMapping.values().contains(type) ||
importMapping.values().contains(type) ||
defaultIncludes.contains(type) ||
languageSpecificPrimitives.contains(type)) {
return type;
} else {
String typeName = sanitizeName(type);
return modelNamePrefix + Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
}
}
@Override
public String toVarName(String name) {
// sanitize name
@ -424,22 +391,6 @@ public class CppQt5ClientCodegen extends AbstractCppCodegen implements CodegenCo
return toVarName(name);
}
@Override
public String toApiName(String type) {
return modelNamePrefix + Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
public void setOptionalProjectFileFlag(boolean flag) {
this.optionalProjectFileFlag = flag;
}

View File

@ -34,6 +34,7 @@ import java.util.Map;
import java.util.Set;
public class CppQt5QHttpEngineServerCodegen extends AbstractCppCodegen implements CodegenConfig {
@SuppressWarnings("unused")
private static final Logger LOGGER = LoggerFactory.getLogger(CppQt5QHttpEngineServerCodegen.class);
public static final String CPP_NAMESPACE = "cppNamespace";
@ -234,7 +235,7 @@ public class CppQt5QHttpEngineServerCodegen extends AbstractCppCodegen implement
}
/**
* Returns human-friendly help for the generator. Provide the consumer with help
* Returns human-friendly help for the generator. Provide the consumer with help
* tips, parameters here
*
* @return A string value for the help message
@ -262,21 +263,7 @@ public class CppQt5QHttpEngineServerCodegen extends AbstractCppCodegen implement
return "#include \"" + folder + name + ".h\"";
}
/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
* those terms here. This logic is only called if a variable matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
/**
* Location to write model files. You can use the modelPackage() as defined when the class is
* instantiated
@ -327,6 +314,7 @@ public class CppQt5QHttpEngineServerCodegen extends AbstractCppCodegen implement
* @return a string value used as the `dataType` field for model templates, `returnType` for api templates
*/
@Override
@SuppressWarnings("rawtypes")
public String getTypeDeclaration(Schema p) {
String openAPIType = getSchemaType(p);
@ -352,6 +340,7 @@ public class CppQt5QHttpEngineServerCodegen extends AbstractCppCodegen implement
}
@Override
@SuppressWarnings("rawtypes")
public String toDefaultValue(Schema p) {
if (ModelUtils.isBooleanSchema(p)) {
return "false";
@ -391,6 +380,7 @@ public class CppQt5QHttpEngineServerCodegen extends AbstractCppCodegen implement
* @return a string value of the type or complex model for this property
*/
@Override
@SuppressWarnings("rawtypes")
public String getSchemaType(Schema p) {
String openAPIType = super.getSchemaType(p);
@ -409,24 +399,6 @@ public class CppQt5QHttpEngineServerCodegen extends AbstractCppCodegen implement
return toModelName(type);
}
@Override
public String toModelName(String type) {
if (type == null) {
LOGGER.warn("Model name can't be null. Defaul to 'UnknownModel'.");
type = "UnknownModel";
}
if (typeMapping.keySet().contains(type) ||
typeMapping.values().contains(type) ||
importMapping.values().contains(type) ||
defaultIncludes.contains(type) ||
languageSpecificPrimitives.contains(type)) {
return type;
} else {
return modelNamePrefix + Character.toUpperCase(type.charAt(0)) + type.substring(1);
}
}
@Override
public String toVarName(String name) {
// sanitize name
@ -455,22 +427,6 @@ public class CppQt5QHttpEngineServerCodegen extends AbstractCppCodegen implement
return toVarName(name);
}
@Override
public String toApiName(String type) {
return modelNamePrefix + Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String getTypeDeclaration(String str) {
return str;

View File

@ -157,7 +157,7 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
typeMapping.put("binary", "std::string");
typeMapping.put("number", "double");
typeMapping.put("UUID", "utility::string_t");
typeMapping.put("ByteArray", "utility::string_t");
typeMapping.put("ByteArray", "utility::string_t");
super.importMapping = new HashMap<String, String>();
importMapping.put("std::vector", "#include <vector>");
@ -200,6 +200,7 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
* Location to write model files. You can use the modelPackage() as defined
* when the class is instantiated
*/
@Override
public String modelFileFolder() {
return outputFolder + "/model";
}
@ -218,7 +219,7 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
if (importMapping.containsKey(name)) {
return importMapping.get(name);
} else {
return "#include \"" + name + ".h\"";
return "#include \"" + sanitizeName(name) + ".h\"";
}
}
@ -281,12 +282,12 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
@Override
public String toModelFilename(String name) {
return initialCaps(name);
return sanitizeName(initialCaps(name));
}
@Override
public String toApiFilename(String name) {
return initialCaps(name) + "Api";
return sanitizeName(initialCaps(name) + "Api");
}
/**
@ -388,33 +389,6 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
return toModelName(type);
}
@Override
public String toModelName(String type) {
if (typeMapping.keySet().contains(type) || typeMapping.values().contains(type)
|| importMapping.values().contains(type) || defaultIncludes.contains(type)
|| languageSpecificPrimitives.contains(type)) {
return type;
} else {
return Character.toUpperCase(type.charAt(0)) + type.substring(1);
}
}
@Override
public String toApiName(String type) {
return Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public Map<String, Object> postProcessAllModels(final Map<String, Object> models) {

View File

@ -148,18 +148,6 @@ public class CppRestbedServerCodegen extends AbstractCppCodegen {
additionalProperties.put("defaultInclude", defaultInclude);
}
/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle
* escaping those terms here. This logic is only called if a variable
* matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
}
/**
* Location to write model files. You can use the modelPackage() as defined
* when the class is instantiated
@ -361,33 +349,4 @@ public class CppRestbedServerCodegen extends AbstractCppCodegen {
type = openAPIType;
return toModelName(type);
}
@Override
public String toModelName(String type) {
if (typeMapping.keySet().contains(type) || typeMapping.values().contains(type)
|| importMapping.values().contains(type) || defaultIncludes.contains(type)
|| languageSpecificPrimitives.contains(type)) {
return type;
} else {
return Character.toUpperCase(type.charAt(0)) + type.substring(1);
}
}
@Override
public String toApiName(String type) {
return Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
}

View File

@ -32,7 +32,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
public class CppTizenClientCodegen extends DefaultCodegen implements CodegenConfig {
public class CppTizenClientCodegen extends AbstractCppCodegen implements CodegenConfig {
protected static String PREFIX = "ArtikCloud";
protected String sourceFolder = "src";
protected String documentationFolder = "doc";
@ -270,14 +270,6 @@ public class CppTizenClientCodegen extends DefaultCodegen implements CodegenConf
return "" + paramName;
}
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
@ -293,16 +285,13 @@ public class CppTizenClientCodegen extends DefaultCodegen implements CodegenConf
// add_pet_by_id => addPetById
return camelize(operationId, true);
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
/**
* Output the Getter name for boolean property, e.g. getActive
*
* @param name the name of the property
* @return getter name based on naming convention
*/
public String toBooleanGetter(String name) {
return "get" + getterAndSetterCapitalize(name);
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
}

View File

@ -377,8 +377,14 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(operationId)) {
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + underscore("call_" + operationId));
return underscore("call_" + operationId);
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + underscore(sanitizeName("call_" + operationId)));
return underscore(sanitizeName("call_" + operationId));
}
// operationId starts with a number
if (operationId.matches("^\\d.*")) {
LOGGER.warn(operationId + " (starting with a number) cannot be used as method name. Renamed to " + underscore(sanitizeName("call_" + operationId)));
operationId = "call_" + operationId;
}
//return underscore(operationId).replaceAll("[^A-Za-z0-9_]", "");

View File

@ -0,0 +1,285 @@
/*
* 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.models.properties.*;
import io.swagger.v3.oas.models.*;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.parameters.*;
import org.openapitools.codegen.*;
import java.io.File;
import java.util.*;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.PathItem.HttpMethod;
import io.swagger.v3.oas.models.*;
import io.swagger.v3.oas.models.parameters.*;
import io.swagger.v3.core.util.Yaml;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PhpLaravelServerCodegen extends AbstractPhpCodegen {
@SuppressWarnings("hiding")
protected String apiVersion = "1.0.0";
protected String variableNamingConvention = "camelCase";
/**
* Configures the type of generator.
*
* @return the CodegenType for this generator
* @see org.openapitools.codegen.CodegenType
*/
public CodegenType getTag() {
return CodegenType.SERVER;
}
/**
* Configures a friendly name for the generator. This will be used by the generator
* to select the library with the -g flag.
*
* @return the friendly name for the generator
*/
public String getName() {
return "php-laravel";
}
/**
* Returns human-friendly help for the generator. Provide the consumer with help
* tips, parameters here
*
* @return A string value for the help message
*/
public String getHelp() {
return "Generates a PHP laravel server library.";
}
/**
* Class constructor
*/
public PhpLaravelServerCodegen() {
super();
embeddedTemplateDir = templateDir = "php-laravel";
/*
* packPath
*/
invokerPackage = "php-laravel";
packagePath = "";
outputFolder = packagePath + File.separator + srcBasePath;
/*
* Api Package. Optional, if needed, this can be used in templates
*/
apiPackage = "app.Http.Controllers";
/*
* Model Package. Optional, if needed, this can be used in templates
*/
modelPackage = "app.Models";
// template files want to be ignored
apiTestTemplateFiles.clear();
apiDocTemplateFiles.clear();
modelDocTemplateFiles.clear();
/*
* Additional Properties. These values can be passed to the templates and
* are available in models, apis, and supporting files
*/
additionalProperties.put("apiVersion", apiVersion);
/*
* Supporting Files. You can write single files for the generator with the
* entire object tree available. If the input file has a suffix of `.mustache
* it will be processed by the template engine. Otherwise, it will be copied
*/
supportingFiles.add(new SupportingFile("composer.mustache", outputFolder, "composer.json"));
supportingFiles.add(new SupportingFile("README.md", outputFolder, "README.md"));
supportingFiles.add(new SupportingFile("artisan", outputFolder, "artisan"));
supportingFiles.add(new SupportingFile("package.json", outputFolder, "package.json"));
supportingFiles.add(new SupportingFile("phpunit.xml", outputFolder, "phpunit.xml"));
supportingFiles.add(new SupportingFile("webpack.mix.js", outputFolder, "webpack.mix.js"));
supportingFiles.add(new SupportingFile(".env.example", outputFolder, ".env.example"));
supportingFiles.add(new SupportingFile("server.php", outputFolder, "server.php"));
supportingFiles.add(new SupportingFile("bootstrap/cache/.gitignore", outputFolder + File.separator + "bootstrap" + File.separator + "cache", ".gitignore"));
supportingFiles.add(new SupportingFile("bootstrap/app.php", outputFolder + File.separator + "bootstrap", "app.php"));
supportingFiles.add(new SupportingFile("bootstrap/testingAutoload.php", outputFolder + File.separator + "bootstrap", "testingAutoload.php"));
/* /public/ */
supportingFiles.add(new SupportingFile("public/css/app.css", outputFolder + File.separator + "public" + File.separator + "css", "app.css"));
supportingFiles.add(new SupportingFile("public/js/app.js", outputFolder + File.separator + "public" + File.separator + "js", "app.js"));
supportingFiles.add(new SupportingFile("public/.htaccess", outputFolder + File.separator + "public", ".htaccess"));
supportingFiles.add(new SupportingFile("public/favicon.ico", outputFolder + File.separator + "public", "favicon.ico"));
supportingFiles.add(new SupportingFile("public/index.php", outputFolder + File.separator + "public", "index.php"));
supportingFiles.add(new SupportingFile("public/robots.txt", outputFolder + File.separator + "public", "robots.txt"));
supportingFiles.add(new SupportingFile("public/web.config", outputFolder + File.separator + "public", "web.config"));
/* /routes/ */
supportingFiles.add(new SupportingFile("routes/api.mustache", outputFolder + File.separator + "routes", "api.php"));
supportingFiles.add(new SupportingFile("routes/web.mustache", outputFolder + File.separator + "routes", "web.php"));
supportingFiles.add(new SupportingFile("routes/channels.mustache", outputFolder + File.separator + "routes", "channels.php"));
supportingFiles.add(new SupportingFile("routes/console.mustache", outputFolder + File.separator + "routes", "console.php"));
/* /app/Http/Controllers/ */
supportingFiles.add(new SupportingFile("app/Http/Kernel.php", outputFolder + File.separator + "app" + File.separator + "Http", "Kernel.php"));
supportingFiles.add(new SupportingFile("app/Http/Controllers/Controller.php", outputFolder + File.separator + "app" + File.separator + "Http" + File.separator + "Controllers", "Controller.php"));
supportingFiles.add(new SupportingFile("app/Http/Middleware/EncryptCookies.php", outputFolder + File.separator + "app" + File.separator + "Http" + File.separator + "Middleware", "EncryptCookies.php"));
supportingFiles.add(new SupportingFile("app/Http/Middleware/RedirectIfAuthenticated.php", outputFolder + File.separator + "app" + File.separator + "Http" + File.separator + "Middleware", "RedirectIfAuthenticated.php"));
supportingFiles.add(new SupportingFile("app/Http/Middleware/TrimStrings.php", outputFolder + File.separator + "app" + File.separator + "Http" + File.separator + "Middleware", "TrimStrings.php"));
supportingFiles.add(new SupportingFile("app/Http/Middleware/TrustProxies.php", outputFolder + File.separator + "app" + File.separator + "Http" + File.separator + "Middleware", "TrustProxies.php"));
supportingFiles.add(new SupportingFile("app/Http/Middleware/VerifyCsrfToken.php", outputFolder + File.separator + "app" + File.separator + "Http" + File.separator + "Middleware", "VerifyCsrfToken.php"));
// /app/Console
supportingFiles.add(new SupportingFile("app/Console/Kernel.php", outputFolder + File.separator + "app" + File.separator + "Console", "Kernel.php"));
// /app/Exceptions
supportingFiles.add(new SupportingFile("app/Exceptions/Handler.php", outputFolder + File.separator + "app" + File.separator + "Exceptions", "Handler.php"));
// /app/Providers
supportingFiles.add(new SupportingFile("app/Providers/AppServiceProvider.php", outputFolder + File.separator + "app" + File.separator + "Providers", "AppServiceProvider.php"));
supportingFiles.add(new SupportingFile("app/Providers/AuthServiceProvider.php", outputFolder + File.separator + "app" + File.separator + "Providers", "AuthServiceProvider.php"));
supportingFiles.add(new SupportingFile("app/Providers/BroadcastServiceProvider.php", outputFolder + File.separator + "app" + File.separator + "Providers", "BroadcastServiceProvider.php"));
supportingFiles.add(new SupportingFile("app/Providers/EventServiceProvider.php", outputFolder + File.separator + "app" + File.separator + "Providers", "EventServiceProvider.php"));
supportingFiles.add(new SupportingFile("app/Providers/RouteServiceProvider.php", outputFolder + File.separator + "app" + File.separator + "Providers", "RouteServiceProvider.php"));
// /database/
supportingFiles.add(new SupportingFile("database/factories/UserFactory.php", outputFolder + File.separator + "database" + File.separator + "factories", "UserFactory.php"));
supportingFiles.add(new SupportingFile("database/migrations/2014_10_12_000000_create_users_table.php", outputFolder + File.separator + "database" + File.separator + "migrations", "2014_10_12_000000_create_users_table.php"));
supportingFiles.add(new SupportingFile("database/migrations/2014_10_12_100000_create_password_resets_table.php", outputFolder + File.separator + "database" + File.separator + "migrations", "2014_10_12_100000_create_password_resets_table.php"));
supportingFiles.add(new SupportingFile("database/seeds/DatabaseSeeder.php", outputFolder + File.separator + "database" + File.separator + "seeds", "DatabaseSeeder.php"));
supportingFiles.add(new SupportingFile("database/.gitignore", outputFolder + File.separator + "database", ".gitignore"));
// /config/
supportingFiles.add(new SupportingFile("config/app.php", outputFolder + File.separator + "config", "app.php"));
supportingFiles.add(new SupportingFile("config/auth.php", outputFolder + File.separator + "config", "auth.php"));
supportingFiles.add(new SupportingFile("config/broadcasting.php", outputFolder + File.separator + "config", "broadcasting.php"));
supportingFiles.add(new SupportingFile("config/cache.php", outputFolder + File.separator + "config", "cache.php"));
supportingFiles.add(new SupportingFile("config/database.php", outputFolder + File.separator + "config", "database.php"));
supportingFiles.add(new SupportingFile("config/filesystems.php", outputFolder + File.separator + "config", "filesystems.php"));
supportingFiles.add(new SupportingFile("config/hashing.php", outputFolder + File.separator + "config", "hashing.php"));
supportingFiles.add(new SupportingFile("config/logging.php", outputFolder + File.separator + "config", "logging.php"));
supportingFiles.add(new SupportingFile("config/mail.php", outputFolder + File.separator + "config", "mail.php"));
supportingFiles.add(new SupportingFile("config/queue.php", outputFolder + File.separator + "config", "queue.php"));
supportingFiles.add(new SupportingFile("config/services.php", outputFolder + File.separator + "config", "services.php"));
supportingFiles.add(new SupportingFile("config/session.php", outputFolder + File.separator + "config", "session.php"));
supportingFiles.add(new SupportingFile("config/view.php", outputFolder + File.separator + "config", "view.php"));
// /resources/
supportingFiles.add(new SupportingFile("resources/assets/js/components/ExampleComponent.vue", outputFolder + File.separator + "resources" + File.separator + "assets" + File.separator + "js" + File.separator + "components", "ExampleComponent.vue"));
supportingFiles.add(new SupportingFile("resources/assets/js/app.js", outputFolder + File.separator + "resources" + File.separator + "assets" + File.separator + "js", "app.js"));
supportingFiles.add(new SupportingFile("resources/assets/js/bootstrap.js", outputFolder + File.separator + "resources" + File.separator + "assets" + File.separator + "js", "bootstrap.js"));
supportingFiles.add(new SupportingFile("resources/assets/sass/_variables.scss", outputFolder + File.separator + "resources" + File.separator + "assets" + File.separator + "sass", "_variables.scss"));
supportingFiles.add(new SupportingFile("resources/assets/sass/app.scss", outputFolder + File.separator + "resources" + File.separator + "assets" + File.separator + "sass", "app.scss"));
supportingFiles.add(new SupportingFile("resources/lang/en/auth.php", outputFolder + File.separator + "resources" + File.separator + "lang" + File.separator + "en", "auth.php"));
supportingFiles.add(new SupportingFile("resources/lang/en/pagination.php", outputFolder + File.separator + "resources" + File.separator + "lang" + File.separator + "en", "pagination.php"));
supportingFiles.add(new SupportingFile("resources/lang/en/passwords.php", outputFolder + File.separator + "resources" + File.separator + "lang" + File.separator + "en", "passwords.php"));
supportingFiles.add(new SupportingFile("resources/lang/en/validation.php", outputFolder + File.separator + "resources" + File.separator + "lang" + File.separator + "en", "validation.php"));
supportingFiles.add(new SupportingFile("resources/views/welcome.blade.php", outputFolder + File.separator + "resources" + File.separator + "views", "welcome.blade.php"));
// /storage/
supportingFiles.add(new SupportingFile("storage/app/.gitignore", outputFolder + File.separator + "storage" + File.separator + "app", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/app/public/.gitignore", outputFolder + File.separator + "storage" + File.separator + "app" + File.separator + "public", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/.gitignore", outputFolder + File.separator + "storage" + File.separator + "framework", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/cache/.gitignore", outputFolder + File.separator + "storage" + File.separator + "framework" + File.separator + "cache", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/sessions/.gitignore", outputFolder + File.separator + "storage" + File.separator + "framework" + File.separator + "sessions", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/testing/.gitignore", outputFolder + File.separator + "storage" + File.separator + "framework" + File.separator + "testing", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/views/.gitignore", outputFolder + File.separator + "storage" + File.separator + "framework" + File.separator + "views", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/logs/.gitignore", outputFolder + File.separator + "storage" + File.separator + "logs", ".gitignore"));
// /tests/
supportingFiles.add(new SupportingFile("tests/Feature/ExampleTest.php", outputFolder + File.separator + "tests" + File.separator + "Feature", "ExampleTest.php"));
supportingFiles.add(new SupportingFile("tests/Unit/ExampleTest.php", outputFolder + File.separator + "tests" + File.separator + "Unit", "ExampleTest.php"));
supportingFiles.add(new SupportingFile("tests/CreatesApplication.php", outputFolder + File.separator + "tests", "CreatesApplication.php"));
supportingFiles.add(new SupportingFile("tests/TestCase.php", outputFolder + File.separator + "tests", "TestCase.php"));
}
// override with any special post-processing
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
@SuppressWarnings("unchecked")
Map<String, Object> objectMap = (Map<String, Object>) objs.get("operations");
@SuppressWarnings("unchecked")
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
for (CodegenOperation op : operations) {
op.httpMethod = op.httpMethod.toLowerCase();
// check to see if the path contains ".", which is not supported by PHP laravel
// ref: https://github.com/swagger-api/swagger-codegen/issues/6897
if (op.path != null && op.path.contains(".")) {
throw new IllegalArgumentException("'.' (dot) is not supported by PHP laravel. Please refer to https://github.com/swagger-api/swagger-codegen/issues/6897 for more info.");
}
if (op.hasProduces) {
// need to escape */* values because they breakes current mustaches
List<Map<String, String>> c = op.produces;
for (Map<String, String> mediaType : c) {
if ("*/*".equals(mediaType.get("mediaType"))) {
mediaType.put("mediaType", "*_/_*");
}
}
}
}
// sort the endpoints in ascending to avoid the route priority issure.
// https://github.com/swagger-api/swagger-codegen/issues/2643
Collections.sort(operations, new Comparator<CodegenOperation>() {
@Override
public int compare(CodegenOperation lhs, CodegenOperation rhs) {
return lhs.path.compareTo(rhs.path);
}
});
return objs;
}
@Override
public String toApiName(String name) {
if (name.isEmpty()) {
return "DefaultController";
}
return camelize(name, false) + "Controller";
}
protected String controllerFileFolder() {
return (outputFolder + File.separator + srcBasePath + File.separator + "app" + File.separator + "Http" + File.separator + "Controllers");
}
@Override
public String apiFilename(String templateName, String tag) {
String suffix = apiTemplateFiles().get(templateName);
if (templateName.equals("api.mustache")) {
return controllerFileFolder() + '/' + toControllerName(tag) + suffix;
}
return apiFileFolder() + '/' + toApiFilename(tag) + suffix;
}
protected String toControllerName(String name) {
if (name.isEmpty()) {
return "DefaultController";
}
return camelize(name, false) + "Controller";
}
}

View File

@ -160,7 +160,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC)
.defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(CodegenConstants.SOURCECODEONLY_GENERATION, CodegenConstants.SOURCECODEONLY_GENERATION_DESC)
.defaultValue(Boolean.FALSE.toString()));
.defaultValue(Boolean.FALSE.toString()));
supportedLibraries.put("urllib3", "urllib3-based client");
supportedLibraries.put("asyncio", "Asyncio-based client (python 3.5+)");
@ -224,7 +224,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
setPackageUrl((String) additionalProperties.get(PACKAGE_URL));
}
String readmePath ="README.md";
String readmePath = "README.md";
String readmeTemplate = "README.mustache";
if (generateSourceCodeOnly) {
readmePath = packageName + "_" + readmePath;
@ -232,7 +232,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
}
supportingFiles.add(new SupportingFile(readmeTemplate, "", readmePath));
if (!generateSourceCodeOnly){
if (!generateSourceCodeOnly) {
supportingFiles.add(new SupportingFile("tox.mustache", "", "tox.ini"));
supportingFiles.add(new SupportingFile("test-requirements.mustache", "", "test-requirements.txt"));
supportingFiles.add(new SupportingFile("requirements.mustache", "", "requirements.txt"));
@ -552,6 +552,12 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
operationId = "call_" + operationId;
}
// operationId starts with a number
if (operationId.matches("^\\d.*")) {
LOGGER.warn(operationId + " (starting with a number) cannot be used as method name. Renamed to " + underscore(sanitizeName("call_" + operationId)));
operationId = "call_" + operationId;
}
return underscore(sanitizeName(operationId));
}

View File

@ -462,6 +462,12 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
return newOperationId;
}
// operationId starts with a number
if (operationId.matches("^\\d.*")) {
LOGGER.warn(operationId + " (starting with a number) cannot be used as method name. Renamed to " + underscore(sanitizeName("call_" + operationId)));
operationId = "call_" + operationId;
}
return underscore(sanitizeName(operationId));
}

View File

@ -19,7 +19,10 @@ package org.openapitools.codegen.languages;
import java.text.SimpleDateFormat;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.SupportingFile;
import io.swagger.v3.oas.models.media.*;
@ -64,6 +67,8 @@ public class RubyOnRailsServerCodegen extends AbstractRubyCodegen {
protected String pidFolder = tmpFolder + File.separator + "pids";
protected String socketsFolder = tmpFolder + File.separator + "sockets";
protected String vendorFolder = "vendor";
protected String databaseAdapter = "sqlite";
public RubyOnRailsServerCodegen() {
super();
@ -87,6 +92,9 @@ public class RubyOnRailsServerCodegen extends AbstractRubyCodegen {
// remove modelPackage and apiPackage added by default
cliOptions.clear();
cliOptions.add(new CliOption(CodegenConstants.DATABASE_ADAPTER, CodegenConstants.DATABASE_ADAPTER_DESC).
defaultValue("sqlite"));
}
@Override
@ -97,7 +105,24 @@ public class RubyOnRailsServerCodegen extends AbstractRubyCodegen {
//setModelPackage("models");
setApiPackage("app/controllers");
supportingFiles.add(new SupportingFile("Gemfile", "", "Gemfile"));
// determine which db adapter to use
if (additionalProperties.containsKey(CodegenConstants.DATABASE_ADAPTER)) {
setDatabaseAdapter((String) additionalProperties.get(CodegenConstants.DATABASE_ADAPTER));
} else {
// not set, pass the default value to template
additionalProperties.put(CodegenConstants.DATABASE_ADAPTER, databaseAdapter);
}
if ("sqlite".equals(databaseAdapter)) {
additionalProperties.put("isDBSQLite", Boolean.TRUE);
} else if ("mysql".equals(databaseAdapter)) {
additionalProperties.put("isDBMySQL", Boolean.TRUE);
} else {
LOGGER.warn("Unknown database {}. Defaul to 'sqlite'.", databaseAdapter);
additionalProperties.put("isDBSQLite", Boolean.TRUE);
}
supportingFiles.add(new SupportingFile("Gemfile.mustache", "", "Gemfile"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
supportingFiles.add(new SupportingFile("Rakefile", "", "Rakefile"));
supportingFiles.add(new SupportingFile("config.ru", "", "config.ru"));
@ -130,7 +155,7 @@ public class RubyOnRailsServerCodegen extends AbstractRubyCodegen {
supportingFiles.add(new SupportingFile("application.rb", configFolder, "application.rb"));
supportingFiles.add(new SupportingFile("boot.rb", configFolder, "boot.rb"));
supportingFiles.add(new SupportingFile("cable.yml", configFolder, "cable.yml"));
supportingFiles.add(new SupportingFile("database.yml", configFolder, "database.yml"));
supportingFiles.add(new SupportingFile("database.mustache", configFolder, "database.yml"));
supportingFiles.add(new SupportingFile("environment.rb", configFolder, "environment.rb"));
supportingFiles.add(new SupportingFile("puma.rb", configFolder, "puma.rb"));
supportingFiles.add(new SupportingFile("routes.mustache", configFolder, "routes.rb"));
@ -156,6 +181,8 @@ public class RubyOnRailsServerCodegen extends AbstractRubyCodegen {
supportingFiles.add(new SupportingFile(".keep", socketsFolder, ".keep"));
supportingFiles.add(new SupportingFile("restart.txt", tmpFolder, "restart.txt"));
supportingFiles.add(new SupportingFile(".keep", vendorFolder, ".keep"));
supportingFiles.add(new SupportingFile("Dockerfile", "", "Dockerfile"));
supportingFiles.add(new SupportingFile("docker-entrypoint.sh", "", "docker-entrypoint.sh"));
}
@Override
@ -225,12 +252,22 @@ public class RubyOnRailsServerCodegen extends AbstractRubyCodegen {
return underscore(name) + "_controller";
}
@Override
public String toApiVarName(String name) {
if (name.length() == 0) {
return "api";
}
// e.g. PhoneNumber => phone_number
return underscore(sanitizeName(name));
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "ApiController";
}
// e.g. phone_number_api => PhoneNumberApi
// e.g. phone_number_controller => PhoneNumberController
return camelize(name) + "Controller";
}
@ -239,4 +276,8 @@ public class RubyOnRailsServerCodegen extends AbstractRubyCodegen {
generateYAMLSpecFile(objs);
return super.postProcessSupportingFileData(objs);
}
public void setDatabaseAdapter(String databaseAdapter) {
this.databaseAdapter = databaseAdapter;
}
}

View File

@ -1030,21 +1030,28 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
if (cm.dataType != null && cm.dataType.equals("object")) {
// Object isn't a sensible default. Instead, we set it to
// 'null'. This ensures that we treat this model as a struct
// with multiple parameters.
cm.dataType = null;
} else if (cm.dataType != null) {
// We need to hack about with single-parameter models to get
// them recognised correctly.
cm.isAlias = false;
cm.dataType = typeMapping.get(cm.dataType);
if (cm.dataType.equals("map")) {
// We don't yet support `additionalProperties`. We ignore
// the `additionalProperties` type ('map') and warn the
// user. This will produce code that compiles, but won't
// feature the `additionalProperties`.
cm.dataType = null;
LOGGER.warn("Ignoring unsupported additionalProperties (see https://github.com/OpenAPITools/openapi-generator/issues/318)");
} else {
// We need to hack about with single-parameter models to
// get them recognised correctly.
cm.isAlias = false;
cm.dataType = typeMapping.get(cm.dataType);
}
}
}
return super.postProcessModelsEnum(objs);
}
private boolean paramHasXmlNamespace(CodegenParameter param, Map<String, Schema> definitions) {

View File

@ -85,7 +85,9 @@ public class {{classname}} {
{{/isDeprecated}}
public class {{operationIdCamelCase}}Oper {
public static final String REQ_METHOD = "{{httpMethod}}";
public static final String REQ_URI = "{{path}}";
public static final String SUMMARY = "{{{summary}}}";
private RequestSpecBuilder reqSpec;
@ -141,7 +143,7 @@ public class {{classname}} {
{{#bodyParams}}
/**
* @param {{paramName}} ({{dataType}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
* @param {{paramName}} ({{{dataType}}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
* @return operation
*/
public {{operationIdCamelCase}}Oper body({{{dataType}}} {{paramName}}) {
@ -154,7 +156,7 @@ public class {{classname}} {
public static final String {{#convert}}{{paramName}}{{/convert}}_HEADER = "{{baseName}}";
/**
* @param {{paramName}} ({{dataType}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
* @param {{paramName}} ({{{dataType}}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
* @return operation
*/
public {{operationIdCamelCase}}Oper {{paramName}}Header(String {{paramName}}) {
@ -167,7 +169,7 @@ public class {{classname}} {
public static final String {{#convert}}{{paramName}}{{/convert}}_PATH = "{{baseName}}";
/**
* @param {{paramName}} ({{dataType}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
* @param {{paramName}} ({{{dataType}}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
* @return operation
*/
public {{operationIdCamelCase}}Oper {{paramName}}Path(Object {{paramName}}) {
@ -180,7 +182,7 @@ public class {{classname}} {
public static final String {{#convert}}{{paramName}}{{/convert}}_QUERY = "{{baseName}}";
/**
* @param {{paramName}} ({{dataType}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
* @param {{paramName}} ({{{dataType}}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
* @return operation
*/
public {{operationIdCamelCase}}Oper {{paramName}}Query(Object... {{paramName}}) {
@ -194,7 +196,7 @@ public class {{classname}} {
public static final String {{#convert}}{{paramName}}{{/convert}}_FORM = "{{baseName}}";
/**
* @param {{paramName}} ({{dataType}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
* @param {{paramName}} ({{{dataType}}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
* @return operation
*/
public {{operationIdCamelCase}}Oper {{paramName}}Form(Object... {{paramName}}) {
@ -209,7 +211,7 @@ public class {{classname}} {
/**
* It will assume that the control name is file and the &lt;content-type&gt; is &lt;application/octet-stream&gt;
* @see #reqSpec for customise
* @param {{paramName}} ({{dataType}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
* @param {{paramName}} ({{{dataType}}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
* @return operation
*/
public {{operationIdCamelCase}}Oper {{paramName}}MultiPart({{{dataType}}} {{paramName}}) {
@ -241,4 +243,4 @@ public class {{classname}} {
}
{{/operation}}
{{/operations}}
}
}

View File

@ -46,6 +46,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
@ -542,8 +544,15 @@ public class ApiClient {
}
builder.queryParams(queryParams);
}
URI uri;
try {
uri = new URI(builder.build().toUriString());
} catch(URISyntaxException ex) {
throw new RestClientException("Could not build URL: " + builder.toUriString(), ex);
}
final BodyBuilder requestBuilder = RequestEntity.method(method, builder.build().toUri());
final BodyBuilder requestBuilder = RequestEntity.method(method, uri);
if(accept != null) {
requestBuilder.accept(accept.toArray(new MediaType[accept.size()]));
}

View File

@ -56,6 +56,7 @@ org.openapitools.codegen.languages.OpenAPIGenerator
org.openapitools.codegen.languages.OpenAPIYamlGenerator
org.openapitools.codegen.languages.PerlClientCodegen
org.openapitools.codegen.languages.PhpClientCodegen
org.openapitools.codegen.languages.PhpLaravelServerCodegen
org.openapitools.codegen.languages.PhpLumenServerCodegen
org.openapitools.codegen.languages.PhpSlimServerCodegen
org.openapitools.codegen.languages.PhpSilexServerCodegen

View File

@ -1,4 +1,4 @@
public class Swagger {
public class OAS {
private static final String HEADER_CONTENT_TYPE = 'Content-Type';
private static final String HEADER_ACCEPT = 'Accept';
private static final String HEADER_ACCEPT_DELIMITER = ',';
@ -271,9 +271,7 @@ public class Swagger {
@TestVisible
protected virtual void applyAuthentication(List<String> names, Map<String, Object> headers,
List<Param> query) {
for (Authentication auth : getAuthMethods(names)) {
auth.apply(headers, query);
}
// TODO Check auth methods
}
@TestVisible
@ -298,7 +296,7 @@ public class Swagger {
protected virtual String toEndpoint(String path, Map<String, Object> params,
List<Param> queryParams) {
String query = '?' + paramsToString(queryParams);
return '"callout:' + calloutName + toPath(path, params) + query.removeEnd('?') + '""';
return 'callout:' + calloutName + toPath(path, params) + query.removeEnd('?');
}
@TestVisible

View File

@ -1,9 +1,9 @@
@isTest
public class SwaggerResponseMock implements HttpCalloutMock {
public class OASResponseMock implements HttpCalloutMock {
private final HttpResponse response;
private HttpRequest request;
public SwaggerResponseMock(HttpResponse response) {
public OASResponseMock(HttpResponse response) {
this.response = response;
}

View File

@ -1,19 +1,19 @@
@isTest
private class SwaggerTest {
private class OASTest {
@isTest
private static void Param_urlEncodeKeyValuePairUtf8() {
String toEncodeLeft = 'Hello +%-_.!~*\'()@';
String toEncodeRight = 'World +%-_.!~*\'()@';
String expected = 'Hello+%2B%25-_.%21%7E*%27%28%29%40=World+%2B%25-_.%21%7E*%27%28%29%40';
String result = new Swagger.Param(toEncodeLeft, toEncodeRight).toString();
String result = new OAS.Param(toEncodeLeft, toEncodeRight).toString();
System.assertEquals(expected, result);
}
@isTest
private static void ApiKeyHeaderAuth_keyInHeaderWithGivenName() {
Map<String, Object> headers = new Map<String, String>();
List<Swagger.Param> query = new List<Swagger.Param>();
Swagger.ApiKeyHeaderAuth auth = new Swagger.ApiKeyHeaderAuth('X-Authenticate');
List<OAS.Param> query = new List<OAS.Param>();
OAS.ApiKeyHeaderAuth auth = new OAS.ApiKeyHeaderAuth('X-Authenticate');
auth.setApiKey('foo-bar-api-key');
auth.apply(headers, query);
@ -25,8 +25,8 @@ private class SwaggerTest {
@isTest
private static void ApiKeyQueryAuth_keyInQueryParamWithGivenName() {
Map<String, Object> headers = new Map<String, String>();
List<Swagger.Param> query = new List<Swagger.Param>();
Swagger.ApiKeyQueryAuth auth = new Swagger.ApiKeyQueryAuth('auth_token');
List<OAS.Param> query = new List<OAS.Param>();
OAS.ApiKeyQueryAuth auth = new OAS.ApiKeyQueryAuth('auth_token');
auth.setApiKey('foo-bar-api-key');
auth.apply(headers, query);
@ -38,8 +38,8 @@ private class SwaggerTest {
@isTest
private static void ApiClient_returnAuthenticationMatchingInput() {
MockApiClient client = new MockApiClient();
Swagger.ApiKeyHeaderAuth auth1 = new Swagger.ApiKeyHeaderAuth('foo');
Swagger.ApiKeyQueryAuth auth2 = new Swagger.ApiKeyQueryAuth('foo');
OAS.ApiKeyHeaderAuth auth1 = new OAS.ApiKeyHeaderAuth('foo');
OAS.ApiKeyQueryAuth auth2 = new OAS.ApiKeyQueryAuth('foo');
client.authentications.put('auth1', auth1);
client.authentications.put('auth2', auth2);
@ -51,8 +51,8 @@ private class SwaggerTest {
@isTest
private static void ApiClient_oneKeyValuePairForEachValueInList() {
List<Object> values = new List<Object>{'bar', 4, false, 12.4, ''};
Swagger.ApiClient client = new Swagger.ApiClient();
List<Swagger.Param> params = client.makeParams('foo', values);
OAS.ApiClient client = new OAS.ApiClient();
List<OAS.Param> params = client.makeParams('foo', values);
System.assertEquals(5, params.size());
System.assertEquals('foo=bar', params.get(0).toString());
@ -64,8 +64,8 @@ private class SwaggerTest {
@isTest
private static void ApiClient_nullMultiValuesListToEmptyParamsList() {
Swagger.ApiClient client = new Swagger.ApiClient();
List<Swagger.Param> params = client.makeParams('foo', null);
OAS.ApiClient client = new OAS.ApiClient();
List<OAS.Param> params = client.makeParams('foo', null);
System.assert(params.isEmpty());
}
@ -73,8 +73,8 @@ private class SwaggerTest {
@isTest
private static void ApiClient_valuesListToSingleCsvKeyValuePair() {
List<Object> values = new List<Object>{'bar', 4, false, 12.4, ''};
Swagger.ApiClient client = new Swagger.ApiClient();
List<Swagger.Param> params = client.makeParam('foo', values, 'csv');
OAS.ApiClient client = new OAS.ApiClient();
List<OAS.Param> params = client.makeParam('foo', values, 'csv');
System.assertEquals(1, params.size());
System.assertEquals('foo=bar%2C4%2Cfalse%2C12.4%2C', params.get(0).toString());
@ -83,8 +83,8 @@ private class SwaggerTest {
@isTest
private static void ApiClient_valuesListToSingleSsvKeyValuePair() {
List<Object> values = new List<Object>{'bar', 4, false, 12.4, ''};
Swagger.ApiClient client = new Swagger.ApiClient();
List<Swagger.Param> params = client.makeParam('foo', values, 'ssv');
OAS.ApiClient client = new OAS.ApiClient();
List<OAS.Param> params = client.makeParam('foo', values, 'ssv');
System.assertEquals(1, params.size());
System.assertEquals('foo=bar+4+false+12.4+', params.get(0).toString());
@ -93,8 +93,8 @@ private class SwaggerTest {
@isTest
private static void ApiClient_valuesListToSingleTsvKeyValuePair() {
List<Object> values = new List<Object>{'bar', 4, false, 12.4, ''};
Swagger.ApiClient client = new Swagger.ApiClient();
List<Swagger.Param> params = client.makeParam('foo', values, 'tsv');
OAS.ApiClient client = new OAS.ApiClient();
List<OAS.Param> params = client.makeParam('foo', values, 'tsv');
System.assertEquals(1, params.size());
System.assertEquals('foo=bar%094%09false%0912.4%09', params.get(0).toString());
@ -103,8 +103,8 @@ private class SwaggerTest {
@isTest
private static void ApiClient_valuesListToSinglePipeSeparatedKeyValuePair() {
List<Object> values = new List<Object>{'bar', 4, false, 12.4, ''};
Swagger.ApiClient client = new Swagger.ApiClient();
List<Swagger.Param> params = client.makeParam('foo', values, 'pipes');
OAS.ApiClient client = new OAS.ApiClient();
List<OAS.Param> params = client.makeParam('foo', values, 'pipes');
System.assertEquals(1, params.size());
System.assertEquals('foo=bar%7C4%7Cfalse%7C12.4%7C', params.get(0).toString());
@ -112,16 +112,16 @@ private class SwaggerTest {
@isTest
private static void ApiClient_nullValuesListToEmptyParamsList() {
Swagger.ApiClient client = new Swagger.ApiClient();
List<Swagger.Param> params = client.makeParam('foo', null, 'csv');
OAS.ApiClient client = new OAS.ApiClient();
List<OAS.Param> params = client.makeParam('foo', null, 'csv');
System.assert(params.isEmpty());
}
@isTest
private static void ApiClient_paramsFromAnyPrimitiveTypeDiscardNull() {
Swagger.ApiClient client = new Swagger.ApiClient();
List<Swagger.Param> params = new List<Swagger.Param>();
OAS.ApiClient client = new OAS.ApiClient();
List<OAS.Param> params = new List<OAS.Param>();
params.addAll(client.makeParam('foo', 'bar'));
params.addAll(client.makeParam('foo', 10));
params.addAll(client.makeParam('foo', 12.6));
@ -141,13 +141,13 @@ private class SwaggerTest {
@isTest
private static void ApiClient_requiredParameterPasses() {
Swagger.ApiClient client = new Swagger.ApiClient();
OAS.ApiClient client = new OAS.ApiClient();
client.assertNotNull('foo', 'bar');
}
@isTest
private static void ApiClient_requiredParameterFails() {
Swagger.ApiClient client = new Swagger.ApiClient();
OAS.ApiClient client = new OAS.ApiClient();
try {
client.assertNotNull(null, 'bar');
} catch (NullPointerException e) {
@ -217,7 +217,7 @@ private class SwaggerTest {
'"bat":false'
};
Set<String> actual1 = new Set<String>(client
.toBody('application/json', body1, new List<Swagger.Param>())
.toBody('application/json', body1, new List<OAS.Param>())
.removeStart('{')
.removeEnd('}')
.split(',')
@ -225,12 +225,12 @@ private class SwaggerTest {
System.assertEquals(expected1, actual1);
String body2 = 'Hello, World!';
String actual2 = client.toBody('text/plain', body2, new List<Swagger.Param>());
String actual2 = client.toBody('text/plain', body2, new List<OAS.Param>());
System.assertEquals(body2, actual2);
List<Swagger.Param> form = new List<Swagger.Param>{
new Swagger.Param('hello', 'world'),
new Swagger.Param('date', '2017-01-01 15:00:00')
List<OAS.Param> form = new List<OAS.Param>{
new OAS.Param('hello', 'world'),
new OAS.Param('date', '2017-01-01 15:00:00')
};
String expected3 = 'hello=world&date=2017-01-01+15%3A00%3A00';
String actual3 = client.toBody('application/x-www-form-urlencoded', '', form);
@ -288,11 +288,11 @@ private class SwaggerTest {
MockApiClient client = new MockApiClient();
String path = '/departments/{department}';
Map<String, Object> params = new Map<String, Object>{'department' => 'finance'};
List<Swagger.Param> queryParams = new List<Swagger.Param>{
new Swagger.Param('foo', 'bar'),
new Swagger.Param('bat', '123')
List<OAS.Param> queryParams = new List<OAS.Param>{
new OAS.Param('foo', 'bar'),
new OAS.Param('bat', '123')
};
String expected = 'https://www.mccombs.utexas.edu/departments/finance?foo=bar&bat=123';
String expected = 'callout:Winkelmeyer/departments/finance?foo=bar&bat=123';
String actual = client.toEndpoint(path, params, queryParams);
System.assertEquals(expected, actual);
}
@ -301,7 +301,7 @@ private class SwaggerTest {
private static void ApiClient_returnParsedBody() {
MockApiClient client = new MockApiClient();
HttpResponse res = new HttpResponse();
SwaggerResponseMock mock = new SwaggerResponseMock(res);
OASResponseMock mock = new OASResponseMock(res);
Test.setMock(HttpCalloutMock.class, mock);
res.setStatus('OK');
@ -314,8 +314,8 @@ private class SwaggerTest {
Address a = (Address) client.invoke(
'GET', '/address', '',
new List<Swagger.Param>(),
new List<Swagger.Param>(),
new List<OAS.Param>(),
new List<OAS.Param>(),
new Map<String, Object>(),
new Map<String, Object>(),
new List<String>{'application/json'},
@ -337,7 +337,7 @@ private class SwaggerTest {
private static void ApiClient_noReturnTypeReturnsNull() {
MockApiClient client = new MockApiClient();
HttpResponse res = new HttpResponse();
SwaggerResponseMock mock = new SwaggerResponseMock(res);
OASResponseMock mock = new OASResponseMock(res);
Test.setMock(HttpCalloutMock.class, mock);
res.setStatus('OK');
@ -345,8 +345,8 @@ private class SwaggerTest {
Object o = client.invoke(
'POST', '/address', '',
new List<Swagger.Param>(),
new List<Swagger.Param>(),
new List<OAS.Param>(),
new List<OAS.Param>(),
new Map<String, Object>(),
new Map<String, Object>(),
new List<String>{'application/json'},
@ -358,9 +358,10 @@ private class SwaggerTest {
System.assertEquals(null, o);
}
private class MockApiClient extends Swagger.ApiClient {
private class MockApiClient extends OAS.ApiClient {
public MockApiClient() {
basePath = 'https://www.mccombs.utexas.edu';
basePath = 'https://blog.winkelmeyer.com';
calloutName = 'Winkelmeyer';
}
}
}

View File

@ -116,7 +116,7 @@ HttpBasicAuth {{{name}}} = (HttpBasicAuth) client.getAuthentication('{{{name}}}'
ApiKeyAuth {{{name}}} = (ApiKeyAuth) client.getAuthentication('{{{name}}}');
{{{name}}}.setApiKey('YOUR API KEY');{{/isApiKey}}{{#isOAuth}}
// Configure OAuth2 access token for authorization: {{{name}}}
Swagger.OAuth {{{name}}} = (Swagger.OAuth) client.getAuthentication('{{{name}}}');
OAS.OAuth {{{name}}} = (OAS.OAuth) client.getAuthentication('{{{name}}}');
{{{name}}}.setAccessToken('YOUR ACCESS TOKEN');{{/isOAuth}}
{{/authMethods}}
{{/hasAuthMethods}}
@ -135,7 +135,7 @@ try {
{{#returnType}}
System.debug(result);
{{/returnType}}
} catch (Swagger.ApiException e) {
} catch (OAS.ApiException e) {
// ...handle your exceptions
}{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}}
```

View File

@ -67,7 +67,7 @@ try {
{{#returnType}}
System.debug(result);
{{/returnType}}
} catch (Swagger.ApiException e) {
} catch (OAS.ApiException e) {
// ...handle your exceptions
}{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}}
```
@ -100,7 +100,7 @@ Class | Method | HTTP request | Description
{{/isBasic}}
{{#isOAuth}}- **Type**: OAuth
- **Flow**: {{flow}}
- **Authorizatoin URL**: {{authorizationUrl}}
- **Authorization URL**: {{authorizationUrl}}
- **Scopes**: {{^scopes}}N/A{{/scopes}}
{{#scopes}} - {{scope}}: {{description}}
{{/scopes}}

View File

@ -25,7 +25,7 @@ public class {{classname}} {
{{#returnType}}
* @return {{{returnType}}}
{{/returnType}}
* @throws Swagger.ApiException if fails to make API call
* @throws OAS.ApiException if fails to make API call
*/
public {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#hasParams}}Map<String, Object> params{{/hasParams}}) {
{{#allParams}}
@ -33,7 +33,7 @@ public class {{classname}} {
client.assertNotNull(params.get('{{paramName}}'), '{{paramName}}');
{{/required}}
{{/allParams}}
List<Swagger.Param> query = new List<Swagger.Param>();
List<OAS.Param> query = new List<OAS.Param>();
{{#hasQueryParams}}
// cast query params to verify their expected type
@ -54,7 +54,7 @@ public class {{classname}} {
{{/hasMore}}
{{/queryParams}}
List<Swagger.Param> form = new List<Swagger.Param>();
List<OAS.Param> form = new List<OAS.Param>();
{{#hasFormParams}}
// cast form params to verify their expected type
@ -88,13 +88,13 @@ public class {{classname}} {
{{/headerParams}}
}{{/hasHeaderParams}}{{^hasHeaderParams}}(){{/hasHeaderParams}},
{{#hasProduces}}
new List<String>{ {{#produces}}'{{{mediaType}}}'{{#hasMore}}, {{/hasMore}}{{/produces}} },
new List<String>{ {{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}} },
{{/hasProduces}}
{{^hasProduces}}
new List<String>(),
{{/hasProduces}}
{{#hasConsumes}}
new List<String>{ {{#consumes}}'{{{mediaType}}}'{{#hasMore}}, {{/hasMore}}{{/consumes}} },
new List<String>{ {{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}} },
{{/hasConsumes}}
{{^hasConsumes}}
new List<String>(),

View File

@ -35,7 +35,7 @@ HttpBasicAuth {{{name}}} = (HttpBasicAuth) client.getAuthentication('{{{name}}}'
ApiKeyAuth {{{name}}} = (ApiKeyAuth) client.getAuthentication('{{{name}}}');
{{{name}}}.setApiKey('YOUR API KEY');{{/isApiKey}}{{#isOAuth}}
// Configure OAuth2 access token for authorization: {{{name}}}
Swagger.OAuth {{{name}}} = (Swagger.OAuth) client.getAuthentication('{{{name}}}');
OAS.OAuth {{{name}}} = (OAS.OAuth) client.getAuthentication('{{{name}}}');
{{{name}}}.setAccessToken('YOUR ACCESS TOKEN');{{/isOAuth}}
{{/authMethods}}
{{/hasAuthMethods}}
@ -54,7 +54,7 @@ try {
{{#returnType}}
System.debug(result);
{{/returnType}}
} catch (Swagger.ApiException e) {
} catch (OAS.ApiException e) {
// ...handle your exceptions
}
```

View File

@ -18,7 +18,7 @@ private class {{classname}}Test {
res.setStatusCode(200);
res.setStatus('OK');
{{/restfulCreate}}
Test.setMock(HttpCalloutMock.class, new SwaggerResponseMock(res));
Test.setMock(HttpCalloutMock.class, new OASResponseMock(res));
{{#hasParams}}
Map<String, Object> params = new Map<String, Object>{
@ -34,18 +34,19 @@ private class {{classname}}Test {
{{{returnType}}} response;
{{{returnType}}} expectedResponse;
{{/returnType}}
String js = '';
{{#authMethods}}
client = new {{classPrefix}}Client();
api = new {{classname}}(client);{{#isApiKey}}
((Swagger.ApiKeyAuth){{/isApiKey}} client.getAuthentication('{{name}}');
{{#isApiKey}}
client.setApiKey('foo-bar-api-key');
((OAS.ApiKeyAuth)client.getAuthentication('{{name}}')).setApiKey('foo-bar-api-key');
{{/isApiKey}}
{{#examples}}
js = JSON.serialize({{{deserializedExample}}});
res.setHeader('Content-Type', '{{contentType}}');
res.setBody('{{{example}}}');
res.setBody(js);
expectedResponse = {{{deserializedExample}}};
response = ({{{returnType}}}) api.{{operationId}}({{#hasParams}}params{{/hasParams}});
System.assertEquals(expectedResponse, response);
@ -59,8 +60,9 @@ private class {{classname}}Test {
api = new {{classname}}(new {{classPrefix}}Client());
{{#examples}}
js = JSON.serialize({{{deserializedExample}}});
res.setHeader('Content-Type', '{{contentType}}');
res.setBody('{{{example}}}');
res.setBody(js);
expectedResponse = {{{deserializedExample}}};
response = ({{{returnType}}}) api.{{operationId}}({{#hasParams}}params{{/hasParams}});
System.assertEquals(expectedResponse, response);

View File

@ -62,7 +62,7 @@
<runTest>{{classname}}Test</runTest>
{{/model}}
{{/models}}
<runTest>SwaggerTest</runTest>
<runTest>OASTest</runTest>
</sf:deploy>
</target>
@ -92,7 +92,7 @@
<runTest>{{classname}}Test</runTest>
{{/model}}
{{/models}}
<runTest>SwaggerTest</runTest>
<runTest>OASTest</runTest>
</sf:deploy>
</target>
</project>

View File

@ -1,4 +1,4 @@
public class {{classPrefix}}Client extends Swagger.ApiClient {
public class {{classPrefix}}Client extends OAS.ApiClient {
{{#hasAuthMethods}}
public {{classPrefix}}Client() {
basePath = '{{basePath}}';
@ -6,10 +6,10 @@ public class {{classPrefix}}Client extends Swagger.ApiClient {
{{#authMethods}}
{{#isApiKey}}
{{#isKeyInQuery}}
authentications.put('{{name}}', new Swagger.ApiKeyQueryAuth('{{keyParamName}}'));
authentications.put('{{name}}', new OAS.ApiKeyQueryAuth('{{keyParamName}}'));
{{/isKeyInQuery}}
{{^isKeyInQuery}}
authentications.put('{{name}}', new Swagger.ApiKeyHeaderAuth('{{keyParamName}}'));
authentications.put('{{name}}', new OAS.ApiKeyHeaderAuth('{{keyParamName}}'));
{{/isKeyInQuery}}
{{/isApiKey}}
{{/authMethods}}

View File

@ -1,7 +1,7 @@
#!/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"
# Usage example: /bin/sh ./git_push.sh wing328 OAS-petstore-perl "minor update"
git_user_id=$1
git_repo_id=$2
@ -36,7 +36,7 @@ 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."
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential 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

View File

@ -5,7 +5,7 @@
* {{#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
* NOTE: This class is auto generated by the OAS code generator program.
* https://github.com/OAS-api/OAS-codegen.git
* Do not edit the class manually.
*/

View File

@ -45,15 +45,6 @@ private class {{classname}}Test {
System.assert({{classVarName}}4.equals({{classVarName}}3));
}
@isTest
private static void notEqualsUnlikeInstance() {
{{classname}} {{classVarName}}1 = {{classname}}.getExample();
{{classname}} {{classVarName}}2 = new {{classname}}();
System.assertEquals(false, {{classVarName}}1.equals({{classVarName}}2));
System.assertEquals(false, {{classVarName}}2.equals({{classVarName}}1));
}
@isTest
private static void notEqualsDifferentType() {
{{classname}} {{classVarName}}1 = {{classname}}.getExample();

View File

@ -3,7 +3,7 @@
<fullName>{{appName}} API Client</fullName>
<description>Client library for calling the {{appName}} API.{{#appDescription}}
{{{appDescription}}}{{/appDescription}}
Generated with OpenAPI Generator (https://openapi-generator.tech)</description>
Generated with OAS Codegen (github.com/OAS-api/OAS-codegen)</description>
<types>
{{#apiInfo}}
{{#apis}}
@ -18,9 +18,9 @@ Generated with OpenAPI Generator (https://openapi-generator.tech)</description>
{{/model}}
{{/models}}
<members>{{classPrefix}}Client</members>
<members>Swagger</members>
<members>SwaggerTest</members>
<members>SwaggerResponseMock</members>
<members>OAS</members>
<members>OASTest</members>
<members>OASResponseMock</members>
<name>ApexClass</name>
</types>
<types>

View File

@ -6,13 +6,15 @@ public class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}}{{#interfac
{{#isEnum}}
{{^isContainer}}
{{>modelInnerEnum}}
{{/isContainer}}
{{#isContainer}}
{{#mostInnerItems}}
{{>modelInnerEnum}}
{{/mostInnerItems}}
{{/isContainer}}
{{/isEnum}}
{{#items.isEnum}}
{{#items}}
{{^isContainer}}
{{>modelInnerEnum}}
{{/isContainer}}
{{/items}}
{{/items.isEnum}}
/**
{{#description}}
* {{{description}}}
@ -58,16 +60,17 @@ public class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}}{{#interfac
public static {{classname}} getExample() {
{{classname}} {{classVarName}} = new {{classname}}();
{{#vars}}
{{classVarName}}.{{name}} = {{{example}}};
{{#example}}{{classVarName}}.{{name}} = {{{example}}};{{/example}}
{{/vars}}
return {{classVarName}};
}
public Boolean equals(Object obj) {
if (obj instanceof {{classname}}) {
if (obj instanceof {{classname}}) { {{#hasVars}}
{{classname}} {{classVarName}} = ({{classname}}) obj;
return {{#vars}}this.{{name}} == {{classVarName}}.{{name}}{{#hasMore}}
&& {{/hasMore}}{{/vars}};
&& {{/hasMore}}{{/vars}};{{/hasVars}}{{^hasVars}}
return true;{{/hasVars}}
}
return false;
}

View File

@ -3,7 +3,7 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
{{#vars}}**{{name}}** | {{#isEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}}{{/isEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#readOnly}} [readonly]{{/readOnly}}
{{#vars}}**{{name}}** | {{#isEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isPrimitiveType}}**{{datatype}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{datatype}}**]({{complexType}}.md){{/isPrimitiveType}}{{/isEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#readOnly}} [readonly]{{/readOnly}}
{{/vars}}
{{#vars}}{{#isEnum}}

View File

@ -0,0 +1,8 @@
{
"orgName": "muenzpraeger - René Winkelmeyer",
"edition": "Developer",
"orgPreferences": {
"enabled": ["S1DesktopEnabled"],
"disabled": ["S1EncryptedStoragePref2"]
}
}

View File

@ -0,0 +1,11 @@
{
"packageDirectories": [
{
"path": "force-app",
"default": true
}
],
"namespace": "",
"sfdcLoginUrl": "https://login.salesforce.com",
"sourceApiVersion": "{{apiVersion}}"
}

View File

@ -1,10 +0,0 @@
{
"sfdxSource": true,
"version": "1.0.0",
"sourceFolder": "src/",
"folders": [
"src/classes"
],
"files": [
]
}

View File

@ -1,6 +1,6 @@
{{>licenseInfo}}
#ifndef _{{prefix}}_{{classname}}Handler_H_
#define _{{prefix}}_{{classname}}Handler_H_
#ifndef {{prefix}}_{{classname}}Handler_H
#define {{prefix}}_{{classname}}Handler_H
#include <QObject>
@ -30,4 +30,4 @@ public slots:
}
{{/cppNamespaceDeclarations}}
#endif // _{{prefix}}_{{classname}}Handler_H_
#endif // {{prefix}}_{{classname}}Handler_H

View File

@ -13,6 +13,10 @@ namespace {{this}} {
{{/cppNamespaceDeclarations}}
{{classname}}Request::{{classname}}Request(QHttpEngine::Socket *s, {{classname}}Handler* hdl) : QObject(s), socket(s), handler(hdl) {
auto headers = s->headers();
for(auto itr = headers.begin(); itr != headers.end(); itr++) {
requestHeaders.insert(QString(itr.key()), QString(itr.value()));
}
}
{{classname}}Request::~{{classname}}Request(){
@ -21,16 +25,23 @@ namespace {{this}} {
}
QMap<QString, QString>
{{classname}}Request::getDefaultHeaders(){
return defaultHeaders;
{{classname}}Request::getRequestHeaders() const {
return requestHeaders;
}
void {{classname}}Request::setResponseHeaders(const QMultiMap<QString, QString>& headers){
for(auto itr = headers.begin(); itr != headers.end(); ++itr) {
responseHeaders.insert(itr.key(), itr.value());
}
}
QHttpEngine::Socket* {{classname}}Request::getRawSocket(){
return socket;
}
{{#operations}}{{#operation}}
void {{classname}}Request::{{nickname}}Request({{#hasPathParams}}{{#pathParams}}QString {{{paramName}}}str{{/pathParams}}{{/hasPathParams}}){
void {{classname}}Request::{{nickname}}Request({{#hasPathParams}}{{#pathParams}}const QString& {{{paramName}}}str{{#hasMore}}, {{/hasMore}}{{/pathParams}}{{/hasPathParams}}){
qDebug() << "{{{basePathWithoutHost}}}{{{path}}}";
connect(this, &{{classname}}Request::{{nickname}}, handler, &{{classname}}Handler::{{nickname}});
@ -64,10 +75,10 @@ void {{classname}}Request::{{nickname}}Request({{#hasPathParams}}{{#pathParams}}
{{/isListContainer}}
{{^isListContainer}}
{{^isMapContainer}}
{{#isPrimitive}}
{{#isPrimitiveType}}
{{{dataType}}} {{paramName}};
::{{cppNamespace}}::fromStringValue((QString(socket->readAll()), {{paramName}});
{{/isPrimitive}}
{{/isPrimitiveType}}
{{/isMapContainer}}
{{#isMapContainer}}
QJsonDocument doc;
@ -81,13 +92,13 @@ void {{classname}}Request::{{nickname}}Request({{#hasPathParams}}{{#pathParams}}
}
{{/isMapContainer}}
{{^isMapContainer}}
{{^isPrimitive}}
{{^isPrimitiveType}}
QJsonDocument doc;
socket->readJson(doc);
QJsonObject obj = doc.object();
{{{dataType}}} {{paramName}};
::{{cppNamespace}}::fromJsonValue({{paramName}}, obj);
{{/isPrimitive}}
{{/isPrimitiveType}}
{{/isMapContainer}}
{{/isListContainer}}
{{/bodyParam}}{{/bodyParams}}
@ -97,27 +108,42 @@ void {{classname}}Request::{{nickname}}Request({{#hasPathParams}}{{#pathParams}}
{{/operation}}{{/operations}}
{{#operations}}{{#operation}}void {{classname}}Request::{{nickname}}Response({{#returnType}}{{{returnType}}} res{{/returnType}}){
socket->setStatusCode(QHttpEngine::Socket::OK);
{{#operations}}{{#operation}}void {{classname}}Request::{{nickname}}Response({{#returnType}}const {{{returnType}}}& res{{/returnType}}){
writeResponseHeaders();{{#returnType}}{{^isPrimitiveType}}
QJsonDocument resDoc(::{{cppNamespace}}::toJsonValue(res).to{{^isListContainer}}Object{{/isListContainer}}{{#isListContainer}}Array{{/isListContainer}}());{{/isPrimitiveType}}
socket->writeJson(resDoc);{{#isPrimitiveType}}
socket->write({{#isListContainer}}QString("["+{{/isListContainer}}::{{cppNamespace}}::toStringValue(res){{#isListContainer}}+"]"){{/isListContainer}}.toUtf8());{{/isPrimitiveType}}{{/returnType}}{{^returnType}}
socket->setStatusCode(QHttpEngine::Socket::OK);{{/returnType}}
if(socket->isOpen()){
socket->writeHeaders();
socket->close();
}
}
{{/operation}}{{/operations}}
{{#operations}}{{#operation}}void {{classname}}Request::{{nickname}}Error({{#returnType}}{{{returnType}}} res, {{/returnType}}QNetworkReply::NetworkError error_type, QString& error_str){
Q_UNUSED(error_type);
Q_UNUSED(error_str);
{{/operation}}{{/operations}}
{{#operations}}{{#operation}}void {{classname}}Request::{{nickname}}Error({{#returnType}}const {{{returnType}}}& res, {{/returnType}}QNetworkReply::NetworkError error_type, QString& error_str){
Q_UNUSED(error_type); // TODO: Remap error_type to QHttpEngine::Socket errors
writeResponseHeaders();{{#returnType}}
Q_UNUSED(error_str); // response will be used instead of error string{{^isPrimitiveType}}
QJsonDocument resDoc(::{{cppNamespace}}::toJsonValue(res).to{{^isListContainer}}Object{{/isListContainer}}{{#isListContainer}}Array{{/isListContainer}}());{{/isPrimitiveType}}
socket->writeJson(resDoc);{{#isPrimitiveType}}
socket->write({{#isListContainer}}QString("["+{{/isListContainer}}::{{cppNamespace}}::toStringValue(res){{#isListContainer}}+"]"){{/isListContainer}}.toUtf8());{{/isPrimitiveType}}{{/returnType}}{{^returnType}}
socket->setStatusCode(QHttpEngine::Socket::NotFound);
socket->write(error_str.toUtf8());{{/returnType}}
if(socket->isOpen()){
socket->writeHeaders();
socket->close();
}
}
{{/operation}}{{/operations}}
void {{classname}}Request::sendCustomResponse(QByteArray & res, QNetworkReply::NetworkError error_type){
Q_UNUSED(res); // TODO
Q_UNUSED(error_type); // TODO
}
void {{classname}}Request::sendCustomResponse(QIODevice *res, QNetworkReply::NetworkError error_type){
Q_UNUSED(res); // TODO
Q_UNUSED(error_type); // TODO
}
{{#cppNamespaceDeclarations}}
}

View File

@ -1,9 +1,10 @@
{{>licenseInfo}}
#ifndef _{{prefix}}_{{classname}}Request_H_
#define _{{prefix}}_{{classname}}Request_H_
#ifndef {{prefix}}_{{classname}}Request_H
#define {{prefix}}_{{classname}}Request_H
#include <QObject>
#include <QStringList>
#include <QMultiMap>
#include <QNetworkReply>
#include <QSharedPointer>
@ -24,30 +25,47 @@ public:
{{classname}}Request(QHttpEngine::Socket *s, {{classname}}Handler* handler);
virtual ~{{classname}}Request();
{{#operations}}{{#operation}}void {{nickname}}Request({{#hasPathParams}}{{#pathParams}}QString {{{paramName}}}{{/pathParams}}{{/hasPathParams}});
{{#operations}}{{#operation}}void {{nickname}}Request({{#hasPathParams}}{{#pathParams}}const QString& {{{paramName}}}{{#hasMore}}, {{/hasMore}}{{/pathParams}}{{/hasPathParams}});
{{/operation}}{{/operations}}
{{#operations}}{{#operation}}void {{nickname}}Response({{#returnType}}{{{returnType}}} res{{/returnType}});
{{#operations}}{{#operation}}void {{nickname}}Response({{#returnType}}const {{{returnType}}}& res{{/returnType}});
{{/operation}}{{/operations}}
{{#operations}}{{#operation}}void {{nickname}}Error({{#returnType}}{{{returnType}}} res, {{/returnType}}QNetworkReply::NetworkError error_type, QString& error_str);
{{#operations}}{{#operation}}void {{nickname}}Error({{#returnType}}const {{{returnType}}}& res, {{/returnType}}QNetworkReply::NetworkError error_type, QString& error_str);
{{/operation}}{{/operations}}
QMap<QString, QString> getDefaultHeaders();
void sendCustomResponse(QByteArray & res, QNetworkReply::NetworkError error_type);
void sendCustomResponse(QIODevice *res, QNetworkReply::NetworkError error_type);
QMap<QString, QString> getRequestHeaders() const;
QHttpEngine::Socket* getRawSocket();
void setResponseHeaders(const QMultiMap<QString,QString>& headers);
signals:
{{#operations}}{{#operation}}void {{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/operation}}{{/operations}}
private:
QMap<QString, QString> defaultHeaders;
QMap<QString, QString> requestHeaders;
QMap<QString, QString> responseHeaders;
QHttpEngine::Socket *socket;
{{classname}}Handler *handler;
inline void writeResponseHeaders(){
QHttpEngine::Socket::HeaderMap resHeaders;
for(auto itr = responseHeaders.begin(); itr != responseHeaders.end(); ++itr) {
resHeaders.insert(itr.key().toUtf8(), itr.value().toUtf8());
}
socket->setHeaders(resHeaders);
socket->writeHeaders();
}
};
{{#cppNamespaceDeclarations}}
}
{{/cppNamespaceDeclarations}}
#endif // _{{prefix}}_{{classname}}Request_H_
#endif // {{prefix}}_{{classname}}Request_H

View File

@ -58,10 +58,8 @@ void ApiRouter::setUpRoutes() {
void ApiRouter::processRequest(QHttpEngine::Socket *socket){
if (Routes.contains(socket->path())) {
auto itr = Routes.find(socket->path());
while (itr != Routes.end() && itr.key() == socket->path()) {
itr.value().operator()(socket);
++itr;
for(auto endpoints : Routes.values(socket->path())) {
endpoints.operator()(socket);
}
} else
{ {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#pathParams}}
@ -77,7 +75,7 @@ void ApiRouter::processRequest(QHttpEngine::Socket *socket){
if ((toQHttpEngineMethod("{{httpMethod}}") == socket->method()) && match.hasMatch() ) {
QString pathparam = match.captured(1);
auto reqObj = new {{classname}}Request(socket, {{classname}}ApiHandler);
reqObj->{{nickname}}Request({{#hasPathParams}}{{#pathParams}}pathparam{{/pathParams}}{{/hasPathParams}});;
reqObj->{{nickname}}Request({{#hasPathParams}}{{#pathParams}}pathparam{{/pathParams}}{{/hasPathParams}});
return;
}
}{{/pathParams}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}

View File

@ -28,23 +28,17 @@ namespace {{this}} {
QString toStringValue(const double &value);
template <typename T>
QList<QString> toStringValue(const QList<T> &val) {
QList<QString> strArray;
QString toStringValue(const QList<T> &val) {
QString strArray;
for(auto item : val) {
strArray.append(toStringValue(item));
strArray.append(toStringValue(item) + ",");
}
if(val.count() > 0) {
strArray.chop(1);
}
return strArray;
}
template <typename T>
QMap<QString, QString> toStringValue(const QMap<QString, T> &val) {
QMap<QString, QString> strMap;
for(auto itemkey : val.keys()) {
strMap.insert(itemkey, toStringValue(val.value(itemkey)));
}
return strMap;
}
QJsonValue toJsonValue(const QString &value);
QJsonValue toJsonValue(const QDateTime &value);
QJsonValue toJsonValue(const QByteArray &value);

View File

@ -72,6 +72,7 @@ int main(int argc, char * argv[])
QSharedPointer<{{cppNamespace}}::RequestHandler> handler(new {{cppNamespace}}::RequestHandler());
{{cppNamespace}}::ApiRouter router;
router.setUpRoutes();
QObject::connect(handler.data(), &{{cppNamespace}}::RequestHandler::requestReceived, [&](QHttpEngine::Socket *socket) {
router.processRequest(socket);
});

View File

@ -90,7 +90,7 @@ QJsonObject
{{#vars}}
{{{dataType}}}
{{classname}}::{{getter}}() {
{{classname}}::{{getter}}() const {
return {{name}};
}
void

View File

@ -5,8 +5,8 @@
* {{description}}
*/
#ifndef {{classname}}_H_
#define {{classname}}_H_
#ifndef {{classname}}_H
#define {{classname}}_H
#include <QJsonObject>
@ -35,7 +35,7 @@ public:
void fromJson(QString jsonString) override;
{{#vars}}
{{{dataType}}} {{getter}}();
{{{dataType}}} {{getter}}() const;
void {{setter}}(const {{{dataType}}} &{{name}});
{{/vars}}
@ -53,6 +53,6 @@ private:
}
{{/cppNamespaceDeclarations}}
#endif /* {{classname}}_H_ */
#endif // {{classname}}_H
{{/model}}
{{/models}}

View File

@ -0,0 +1,39 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

View File

@ -0,0 +1,23 @@
# OpenAPI generated server
## Overview
This server was generated by the [openapi-generator](https://github.com/openapitools/openapi-generator) project. By using the
[OpenAPI-Spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This
is an example of building a PHP server.
This example uses the [laravel Framework](http://laravel.com/). To see how to make this your own, please take a look at the template here:
## Installation & Usage
### Composer
Using `composer install` to install the framework and dependencies via [Composer](http://getcomposer.org/).
### post installation steps
Change into application folder and execute following commands to get started:
```sh
cp .env.example .env
php artisan key:generate
php artisan serve
```

View File

@ -0,0 +1,128 @@
<?php
{{>licenseInfo}}
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Request;
{{#operations}}class {{classname}} extends Controller
{
/**
* Constructor
*/
public function __construct()
{
}
{{#operation}}
/**
* Operation {{{operationId}}}
*
* {{{summary}}}.
*
{{#pathParams}} * @param {{dataType}} ${{paramName}} {{description}} {{#required}}(required){{/required}}{{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/pathParams}} *
* @return Http response
*/
public function {{operationId}}({{#pathParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/pathParams}})
{
$input = Request::all();
//path params validation
{{#pathParams}}
{{#hasValidation}}
{{#maxLength}}
if (strlen(${{paramName}}) > {{maxLength}}) {
throw new \InvalidArgumentException('invalid length for ${{paramName}} when calling {{classname}}.{{operationId}}, must be smaller than or equal to {{maxLength}}.');
}
{{/maxLength}}
{{#minLength}}
if (strlen(${{paramName}}) < {{minLength}}) {
throw new \InvalidArgumentException('invalid length for ${{paramName}} when calling {{classname}}.{{operationId}}, must be bigger than or equal to {{minLength}}.');
}
{{/minLength}}
{{#maximum}}
if (${{paramName}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}) {
throw new \InvalidArgumentException('invalid value for ${{paramName}} when calling {{classname}}.{{operationId}}, must be smaller than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}{{maximum}}.');
}
{{/maximum}}
{{#minimum}}
if (${{paramName}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}) {
throw new \InvalidArgumentException('invalid value for ${{paramName}} when calling {{classname}}.{{operationId}}, must be bigger than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}{{minimum}}.');
}
{{/minimum}}
{{#pattern}}
if (!preg_match("{{{pattern}}}", ${{paramName}})) {
throw new \InvalidArgumentException('invalid value for ${{paramName}} when calling {{classname}}.{{operationId}}, must conform to the pattern {{{pattern}}}.');
}
{{/pattern}}
{{#maxItems}}
if (count(${{paramName}}) > {{maxItems}}) {
throw new \InvalidArgumentException('invalid length for ${{paramName}} when calling {{classname}}.{{operationId}}, number of items must be less than or equal to {{maxItems}}.');
}
{{/maxItems}}
{{#minItems}}
if (count(${{paramName}}) < {{minItems}}) {
throw new \InvalidArgumentException('invalid length for ${{paramName}} when calling {{classname}}.{{operationId}}, number of items must be greater than or equal to {{minItems}}.');
}
{{/minItems}}
{{/hasValidation}}
{{/pathParams}}
//not path params validation
{{#allParams}}
{{^pathParams}}
{{#required}}
if (!isset($input['{{paramName}}'])) {
throw new \InvalidArgumentException('Missing the required parameter ${{paramName}} when calling {{operationId}}');
}
{{/required}}
{{#hasValidation}}
{{#maxLength}}
if (strlen($input['{{paramName}}']) > {{maxLength}}) {
throw new \InvalidArgumentException('invalid length for ${{paramName}} when calling {{classname}}.{{operationId}}, must be smaller than or equal to {{maxLength}}.');
}
{{/maxLength}}
{{#minLength}}
if (strlen($input['{{paramName}}']) < {{minLength}}) {
throw new \InvalidArgumentException('invalid length for ${{paramName}} when calling {{classname}}.{{operationId}}, must be bigger than or equal to {{minLength}}.');
}
{{/minLength}}
{{#maximum}}
if ($input['{{paramName}}'] >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}) {
throw new \InvalidArgumentException('invalid value for ${{paramName}} when calling {{classname}}.{{operationId}}, must be smaller than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}{{maximum}}.');
}
{{/maximum}}
{{#minimum}}
if ($input['{{paramName}}'] <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}) {
throw new \InvalidArgumentException('invalid value for ${{paramName}} when calling {{classname}}.{{operationId}}, must be bigger than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}{{minimum}}.');
}
{{/minimum}}
{{#pattern}}
if (!preg_match("{{{pattern}}}", $input['{{paramName}}'])) {
throw new \InvalidArgumentException('invalid value for ${{paramName}} when calling {{classname}}.{{operationId}}, must conform to the pattern {{{pattern}}}.');
}
{{/pattern}}
{{#maxItems}}
if (count($input['{{paramName}}']) > {{maxItems}}) {
throw new \InvalidArgumentException('invalid length for ${{paramName}} when calling {{classname}}.{{operationId}}, number of items must be less than or equal to {{maxItems}}.');
}
{{/maxItems}}
{{#minItems}}
if (count($input['{{paramName}}']) < {{minItems}}) {
throw new \InvalidArgumentException('invalid length for ${{paramName}} when calling {{classname}}.{{operationId}}, number of items must be greater than or equal to {{minItems}}.');
}
{{/minItems}}
{{/hasValidation}}
${{paramName}} = $input['{{paramName}}'];
{{/pathParams}}
{{/allParams}}
return response('How about implementing {{nickname}} as a {{httpMethod}} method ?');
}
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Report or log an exception.
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $exception)
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
return parent::render($request, $exception);
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
/**
* Class Controller
*
* @package App\Http\Controllers
*/
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function welcome()
{
return view('welcome');
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
class EncryptCookies extends Middleware
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array
*/
protected $except = [
//
];
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
class TrimStrings extends Middleware
{
/**
* The names of the attributes that should not be trimmed.
*
* @var array
*/
protected $except = [
'password',
'password_confirmation',
];
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array
*/
protected $proxies;
/**
* The headers that should be used to detect proxies.
*
* @var int
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
//
];
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Broadcast;
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Broadcast::routes();
require base_path('routes/channels.php');
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'App\Events\Event' => [
'App\Listeners\EventListener',
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
//
}
}

View File

@ -0,0 +1,72 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to your controller routes.
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
//
parent::boot();
}
/**
* Define the routes for the application.
*
* @return void
*/
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
//
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*
* @return void
*/
protected function mapApiRoutes()
{
Route::middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}

View File

@ -0,0 +1,53 @@
#!/usr/bin/env php
<?php
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/
require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Artisan Application
|--------------------------------------------------------------------------
|
| When we run the console application, the current CLI command will be
| executed in this console and the response sent back to a terminal
| or another output device for the developers. Here goes nothing!
|
*/
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput,
new Symfony\Component\Console\Output\ConsoleOutput
);
/*
|--------------------------------------------------------------------------
| Shutdown The Application
|--------------------------------------------------------------------------
|
| Once Artisan has finished running, we will fire off the shutdown events
| so that any final work may be done by the application before we shut
| down the process. This is the last thing to happen to the request.
|
*/
$kernel->terminate($input, $status);
exit($status);

View File

@ -0,0 +1,55 @@
<?php
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
/*
|--------------------------------------------------------------------------
| Bind Important Interfaces
|--------------------------------------------------------------------------
|
| Next, we need to bind some important interfaces into the container so
| we will be able to resolve them when needed. The kernels serve the
| incoming requests to this application from both the web and CLI.
|
*/
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/
return $app;

View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -0,0 +1,6 @@
<?php
passthru("php artisan --env='testing' migrate:fresh");
passthru("php artisan --env='testing' db:seed");
require realpath(__DIR__ . '/../vendor/autoload.php');

View File

@ -0,0 +1,66 @@
{
"name": "{{#composerVendorName}}{{.}}{{/composerVendorName}}{{^composerVendorName}}{{gitUserId}}{{/composerVendorName}}/{{#composerProjectName}}{{.}}{{/composerProjectName}}{{^composerProjectName}}{{gitRepoId}}{{/composerProjectName}}",
"description": "{{description}}.",
"keywords": ["framework", "laravel"],
{{#artifactVersion}}
"version": "{{artifactVersion}}",
{{/artifactVersion}}
"license": "MIT",
"type": "project",
"require": {
"php": "^7.1.3",
"fideloper/proxy": "^4.0",
"laravel/framework": "5.6.*",
"laravel/tinker": "^1.0"
},
"require-dev": {
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^2.0",
"phpunit/phpunit": "^7.0",
"phpspec/phpspec": "^4.2",
"squizlabs/php_codesniffer": "^3.0"
},
"autoload": {
"classmap": [
"database/seeds",
"database/migrations",
"database/factories"
],
"psr-4": {
"App\\": "app/",
"Tests\\": "tests/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"extra": {
"laravel": {
"dont-discover": [
]
}
},
"scripts": {
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true
},
"minimum-stability": "dev",
"prefer-stable": true
}

View File

@ -0,0 +1,214 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Application Name
|--------------------------------------------------------------------------
|
| This value is the name of your application. This value is used when the
| framework needs to place the application's name in a notification or
| any other location as required by the application or its packages.
|
*/
'name' => env('APP_NAME', 'Laravel'),
/*
|--------------------------------------------------------------------------
| Application Environment
|--------------------------------------------------------------------------
|
| This value determines the "environment" your application is currently
| running in. This may determine how you prefer to configure various
| services your application utilizes. Set this in your ".env" file.
|
*/
'env' => env('APP_ENV', 'production'),
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
'url' => env('APP_URL', 'http://localhost'),
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'UTC',
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'en',
/*
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/
'fallback_locale' => 'en',
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
'key' => env('APP_KEY'),
'cipher' => 'AES-256-CBC',
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
/*
* Package Service Providers...
*/
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
],
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
'Bus' => Illuminate\Support\Facades\Bus::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class,
'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Notification' => Illuminate\Support\Facades\Notification::class,
'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
],
];

View File

@ -0,0 +1,102 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
];

View File

@ -0,0 +1,59 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Broadcaster
|--------------------------------------------------------------------------
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "pusher", "redis", "log", "null"
|
*/
'default' => env('BROADCAST_DRIVER', 'null'),
/*
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over websockets. Samples of
| each available type of connection are provided inside this array.
|
*/
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => true,
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];

View File

@ -0,0 +1,94 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Cache Store
|--------------------------------------------------------------------------
|
| This option controls the default cache connection that gets used while
| using this caching library. This connection is used when another is
| not explicitly specified when executing a given caching function.
|
| Supported: "apc", "array", "database", "file", "memcached", "redis"
|
*/
'default' => env('CACHE_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------
| Cache Stores
|--------------------------------------------------------------------------
|
| Here you may define all of the cache "stores" for your application as
| well as their drivers. You may even define multiple stores for the
| same cache driver to group types of items stored in your caches.
|
*/
'stores' => [
'apc' => [
'driver' => 'apc',
],
'array' => [
'driver' => 'array',
],
'database' => [
'driver' => 'database',
'table' => 'cache',
'connection' => null,
],
'file' => [
'driver' => 'file',
'path' => storage_path('framework/cache/data'),
],
'memcached' => [
'driver' => 'memcached',
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
],
/*
|--------------------------------------------------------------------------
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing a RAM based store such as APC or Memcached, there might
| be other applications utilizing the same cache. So, we'll specify a
| value to get prefixed to all our keys so we can avoid collisions.
|
*/
'prefix' => env(
'CACHE_PREFIX',
str_slug(env('APP_NAME', 'laravel'), '_').'_cache'
),
];

View File

@ -0,0 +1,120 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
],
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
];

View File

@ -0,0 +1,69 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Filesystem Disk
|--------------------------------------------------------------------------
|
| Here you may specify the default filesystem disk that should be used
| by the framework. The "local" disk, as well as a variety of cloud
| based disks are available to your application. Just store away!
|
*/
'default' => env('FILESYSTEM_DRIVER', 'local'),
/*
|--------------------------------------------------------------------------
| Default Cloud Filesystem Disk
|--------------------------------------------------------------------------
|
| Many applications store files both locally and in the cloud. For this
| reason, you may specify a default "cloud" driver here. This driver
| will be bound as the Cloud disk implementation in the container.
|
*/
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
/*
|--------------------------------------------------------------------------
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
| Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace"
|
*/
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
],
],
];

View File

@ -0,0 +1,52 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Hash Driver
|--------------------------------------------------------------------------
|
| This option controls the default hash driver that will be used to hash
| passwords for your application. By default, the bcrypt algorithm is
| used; however, you remain free to modify this option if you wish.
|
| Supported: "bcrypt", "argon"
|
*/
'driver' => 'bcrypt',
/*
|--------------------------------------------------------------------------
| Bcrypt Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Bcrypt algorithm. This will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'bcrypt' => [
'rounds' => env('BCRYPT_ROUNDS', 10),
],
/*
|--------------------------------------------------------------------------
| Argon Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Argon algorithm. These will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'argon' => [
'memory' => 1024,
'threads' => 2,
'time' => 2,
],
];

View File

@ -0,0 +1,81 @@
<?php
use Monolog\Handler\StreamHandler;
return [
/*
|--------------------------------------------------------------------------
| Default Log Channel
|--------------------------------------------------------------------------
|
| This option defines the default log channel that gets used when writing
| messages to the logs. The name specified in this option should match
| one of the channels defined in the "channels" configuration array.
|
*/
'default' => env('LOG_CHANNEL', 'stack'),
/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the log channels for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Drivers: "single", "daily", "slack", "syslog",
| "errorlog", "monolog",
| "custom", "stack"
|
*/
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 7,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
'stderr' => [
'driver' => 'monolog',
'handler' => StreamHandler::class,
'with' => [
'stream' => 'php://stderr',
],
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
],
'errorlog' => [
'driver' => 'errorlog',
'level' => 'debug',
],
],
];

View File

@ -0,0 +1,123 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "sendmail", "mailgun", "mandrill", "ses",
| "sparkpost", "log", "array"
|
*/
'driver' => env('MAIL_DRIVER', 'smtp'),
/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Mailgun mail service which will provide reliable deliveries.
|
*/
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to deliver e-mails to
| users of the application. Like the host we have set this value to
| stay compatible with the Mailgun e-mail application by default.
|
*/
'port' => env('MAIL_PORT', 587),
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Markdown Mail Settings
|--------------------------------------------------------------------------
|
| If you are using Markdown based email rendering, you may configure your
| theme and component paths here, allowing you to customize the design
| of the emails. Or, you may simply stick with the Laravel defaults!
|
*/
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
];

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