Compare commits

..

6 Commits

Author SHA1 Message Date
William Cheng
bcd0609159 update samples 2022-12-18 22:10:31 +08:00
William Cheng
5050cbfa94 add samples for java resttemplate echo api 2022-12-18 21:00:33 +08:00
William Cheng
e208fe8632 Merge branch 'issue-13393' of https://github.com/aharonha/openapi-generator into aharonha-issue-13393 2022-12-18 20:45:28 +08:00
Aharon Hacmon
d6deaf8c7b 13393: Make queryParams known to UriComponents builder so it can
properly encode them
2022-12-18 10:09:33 +02:00
Aharon Hacmon
d34ac8d13b 13393: Make queryParams known to UriComponents builder so it can
properly encode them
2022-12-18 09:47:26 +02:00
Aharon Hacmon
5a265cc419 13393: Make queryParams known to UriComponents builder so it can
properly encode them
2022-11-27 16:16:28 +02:00
328 changed files with 4679 additions and 14244 deletions

View File

@@ -19,6 +19,7 @@ jobs:
- samples/client/echo_api/java/apache-httpclient
- samples/client/echo_api/java/native
- samples/client/echo_api/java/feign-gson
- samples/client/echo_api/java/resttemplate
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3

View File

@@ -1,49 +0,0 @@
name: Samples Java Server
on:
push:
paths:
# java-camel is tested locally for the time being
#- 'samples/server/petstore/java-camel/**'
- 'samples/server/petstore/java-vertx-web/**'
- 'samples/server/petstore/java-inflector/**'
- 'samples/server/petstore/java-pkmst/**'
- 'samples/server/petstore/java-undertow/**'
pull_request:
paths:
#- 'samples/server/petstore/java-camel/**'
- 'samples/server/petstore/java-vertx-web/**'
- 'samples/server/petstore/java-inflector/**'
- 'samples/server/petstore/java-pkmst/**'
- 'samples/server/petstore/java-undertow/**'
jobs:
build:
name: Build Java Server
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# servers
#- samples/server/petstore/java-camel/
- samples/server/petstore/java-vertx-web/
- samples/server/petstore/java-inflector/
- samples/server/petstore/java-pkmst/
- samples/server/petstore/java-undertow/
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 8
- name: Cache maven dependencies
uses: actions/cache@v3
env:
cache-name: maven-repository
with:
path: |
~/.m2
key: ${{ runner.os }}-${{ github.job }}-${{ env.cache-name }}-${{ hashFiles('**/pom.xml') }}
- name: Build
working-directory: ${{ matrix.sample }}
run: mvn clean package

View File

@@ -877,8 +877,6 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- 2022-10-01 - [OpenAPI Generatorをカスタマイズしたコードを生成するSwagger Codegenとほぼ同じ](https://nainaistar.hatenablog.com/entry/2022/10/03/120000) by [きり丸](https://twitter.com/nainaistar)
- 2022-10-21 - [KotlinSpring Bootの API を OpenAPI Generator で自動生成](https://zenn.dev/msksgm/articles/20221021-kotlin-spring-openapi-generator) by [msksgm](https://zenn.dev/msksgm)
- 2022-10-26 - [Quarkus Insights #106: Quarkiverse Extension Spotlight: OpenApi Generator](https://www.youtube.com/watch?v=_s_if69t2iQ) by [Quarkusio](https://www.youtube.com/c/Quarkusio)
- 2022-11-28 - [The REST API implementation flow](https://tmsvr.com/openapi-code-generation-for-rest-apis/) by [Imre Tömösvári](https://tmsvr.com/author/imre/)
- 2022-12-13 - [API-First with Spring WebFlux and OpenAPI Generator](https://boottechnologies-ci.medium.com/api-first-with-spring-webflux-and-openapi-generator-38b7804c4ed4) by [Eric Anicet](https://boottechnologies-ci.medium.com/)
## [6 - About Us](#table-of-contents)

View File

@@ -0,0 +1,8 @@
generatorName: java
outputDir: samples/client/echo_api/java/resttemplate
library: resttemplate
inputSpec: modules/openapi-generator/src/test/resources/3_0/echo_api.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: echo-api-resttemplate
hideGenerationTimestamp: "true"

View File

@@ -1,10 +0,0 @@
generatorName: swift5
outputDir: samples/client/petstore/swift5/validation
inputSpec: modules/openapi-generator/src/test/resources/3_0/validation.yaml
templateDir: modules/openapi-generator/src/main/resources/swift5
generateAliasAsModel: true
additionalProperties:
podAuthors: ""
podSummary: PetstoreClient
projectName: PetstoreClient
podHomepage: https://github.com/openapitools/openapi-generator

View File

@@ -1,4 +0,0 @@
generatorName: typescript-fetch
outputDir: samples/client/petstore/typescript-fetch/builds/allOf-nullable
inputSpec: modules/openapi-generator/src/test/resources/3_0/allOf-nullable.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-fetch

View File

@@ -1,8 +0,0 @@
generatorName: typescript-koa-server
outputDir: samples/server/petstore/typescript-koa-server
#outputDir: /Users/williamcheng/Code/typescript/PetStore
inputSpec: modules/openapi-generator/src/test/resources/3_0/typescript-koa-server/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-koa-server
additionalProperties:
ngVersion: 15.0.3
supportsES6: true

View File

@@ -56,7 +56,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useCustomDateWithoutTime|Uses a custom type to decode and encode dates without time information to support OpenAPIs date format (default: false)| |false|
|useJsonEncodable|Make models conform to JSONEncodable protocol (default: true)| |true|
|useSPMFileStructure|Use SPM file structure and set the source path to Sources/{{projectName}} (default: false).| |null|
|validatable|Make validation rules and validator for model properies (default: true)| |true|
## IMPORT MAPPING

View File

@@ -196,16 +196,11 @@ public class InlineModelResolver {
// allOf, anyOf, oneOf
ComposedSchema m = (ComposedSchema) schema;
boolean isSingleAllOf = m.getAllOf() != null && m.getAllOf().size() == 1;
boolean isReadOnly = m.getReadOnly() != null && m.getReadOnly();
boolean isNullable = m.getNullable() != null && m.getNullable();
if (isSingleAllOf && (isReadOnly || isNullable)) {
// Check if this composed schema only contains an allOf and a readOnly or nullable.
if (m.getAllOf() != null && m.getAllOf().size() == 1 && m.getReadOnly() != null && m.getReadOnly()) {
// Check if this composed schema only contains an allOf and a readOnly.
ComposedSchema c = new ComposedSchema();
c.setAllOf(m.getAllOf());
c.setReadOnly(m.getReadOnly());
c.setNullable(m.getNullable());
c.setReadOnly(true);
if (m.equals(c)) {
return isModelNeeded(m.getAllOf().get(0), visitedSchemas);
}

View File

@@ -74,7 +74,6 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
public static final String USE_JSON_ENCODABLE = "useJsonEncodable";
public static final String MAP_FILE_BINARY_TO_DATA = "mapFileBinaryToData";
public static final String USE_CUSTOM_DATE_WITHOUT_TIME = "useCustomDateWithoutTime";
public static final String VALIDATABLE = "validatable";
protected static final String LIBRARY_ALAMOFIRE = "alamofire";
protected static final String LIBRARY_URLSESSION = "urlsession";
protected static final String LIBRARY_VAPOR = "vapor";
@@ -100,7 +99,6 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
protected boolean useJsonEncodable = true;
protected boolean mapFileBinaryToData = false;
protected boolean useCustomDateWithoutTime = false;
protected boolean validatable = true;
protected String[] responseAs = new String[0];
protected String sourceFolder = swiftPackagePath;
protected HashSet objcReservedWords;
@@ -318,10 +316,6 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
"Uses a custom type to decode and encode dates without time information to support OpenAPIs date format (default: false)")
.defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(VALIDATABLE,
"Make validation rules and validator for model properies (default: true)")
.defaultValue(Boolean.TRUE.toString()));
supportedLibraries.put(LIBRARY_URLSESSION, "[DEFAULT] HTTP client: URLSession");
supportedLibraries.put(LIBRARY_ALAMOFIRE, "HTTP client: Alamofire");
supportedLibraries.put(LIBRARY_VAPOR, "HTTP client: Vapor");
@@ -545,11 +539,6 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
}
additionalProperties.put(USE_CLASSES, useClasses);
if (additionalProperties.containsKey(VALIDATABLE)) {
setValidatable(convertPropertyToBooleanAndWriteBack(VALIDATABLE));
}
additionalProperties.put(VALIDATABLE, validatable);
setLenientTypeCast(convertPropertyToBooleanAndWriteBack(LENIENT_TYPE_CAST));
// make api and model doc path available in mustache template
@@ -608,11 +597,6 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
supportingFiles.add(new SupportingFile("APIs.mustache",
sourceFolder,
"APIs.swift"));
if (validatable) {
supportingFiles.add(new SupportingFile("Validation.mustache",
sourceFolder,
"Validation.swift"));
}
supportingFiles.add(new SupportingFile("gitignore.mustache",
"",
".gitignore"));
@@ -1013,10 +997,6 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
this.useJsonEncodable = useJsonEncodable;
}
public void setValidatable(boolean validatable) {
this.validatable = validatable;
}
@Override
public String toEnumValue(String value, String datatype) {
// for string, array of string

View File

@@ -1,633 +0,0 @@
/*
* 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
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.DocumentationFeature;
import org.openapitools.codegen.meta.features.GlobalFeature;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.SemVer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.apache.commons.lang3.StringUtils.capitalize;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.StringUtils.*;
public class TypeScriptKoaServerCodegen extends AbstractTypeScriptClientCodegen {
private final Logger LOGGER = LoggerFactory.getLogger(TypeScriptKoaServerCodegen.class);
private static String CLASS_NAME_PREFIX_PATTERN = "^[a-zA-Z0-9]*$";
private static String CLASS_NAME_SUFFIX_PATTERN = "^[a-zA-Z0-9]*$";
private static String FILE_NAME_SUFFIX_PATTERN = "^[a-zA-Z0-9.-]*$";
public static enum QUERY_PARAM_OBJECT_FORMAT_TYPE {dot, json, key}
public static enum PROVIDED_IN_LEVEL {none, root, any, platform}
private static final String DEFAULT_IMPORT_PREFIX = "./";
private static final String DEFAULT_MODEL_IMPORT_DIRECTORY_PREFIX = "../";
public static final String NPM_REPOSITORY = "npmRepository";
public static final String WITH_INTERFACES = "withInterfaces";
public static final String USE_SINGLE_REQUEST_PARAMETER = "useSingleRequestParameter";
public static final String TAGGED_UNIONS = "taggedUnions";
public static final String NG_VERSION = "ngVersion";
public static final String PROVIDED_IN = "providedIn";
public static final String ENFORCE_GENERIC_MODULE_WITH_PROVIDERS = "enforceGenericModuleWithProviders";
public static final String HTTP_CONTEXT_IN_OPTIONS = "httpContextInOptions";
public static final String API_MODULE_PREFIX = "apiModulePrefix";
public static final String CONFIGURATION_PREFIX = "configurationPrefix";
public static final String SERVICE_SUFFIX = "serviceSuffix";
public static final String SERVICE_FILE_SUFFIX = "serviceFileSuffix";
public static final String MODEL_SUFFIX = "modelSuffix";
public static final String MODEL_FILE_SUFFIX = "modelFileSuffix";
public static final String FILE_NAMING = "fileNaming";
public static final String STRING_ENUMS = "stringEnums";
public static final String STRING_ENUMS_DESC = "Generate string enums instead of objects for enum values.";
public static final String QUERY_PARAM_OBJECT_FORMAT = "queryParamObjectFormat";
protected String ngVersion = "15.0.3";
protected String npmRepository = null;
private boolean useSingleRequestParameter = false;
protected String serviceSuffix = "Service";
protected String serviceFileSuffix = ".service";
protected String modelSuffix = "";
protected String modelFileSuffix = "";
protected String fileNaming = "camelCase";
protected Boolean stringEnums = false;
protected QUERY_PARAM_OBJECT_FORMAT_TYPE queryParamObjectFormat = QUERY_PARAM_OBJECT_FORMAT_TYPE.dot;
protected PROVIDED_IN_LEVEL providedIn = PROVIDED_IN_LEVEL.root;
private boolean taggedUnions = false;
public TypeScriptKoaServerCodegen() {
super();
modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.includeGlobalFeatures(GlobalFeature.ParameterStyling)
);
this.outputFolder = "generated-code/typescript-koa";
supportsMultipleInheritance = true;
embeddedTemplateDir = templateDir = "typescript-koa";
modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.service.mustache", ".ts");
languageSpecificPrimitives.add("Blob");
typeMapping.put("file", "Blob");
apiPackage = "api";
modelPackage = "model";
this.cliOptions.add(new CliOption(NPM_REPOSITORY,
"Use this property to set an url your private npmRepo in the package.json"));
this.cliOptions.add(CliOption.newBoolean(WITH_INTERFACES,
"Setting this property to true will generate interfaces next to the default class implementations.",
false));
this.cliOptions.add(CliOption.newBoolean(USE_SINGLE_REQUEST_PARAMETER,
"Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.",
false));
this.cliOptions.add(CliOption.newBoolean(TAGGED_UNIONS,
"Use discriminators to create tagged unions instead of extending interfaces.",
this.taggedUnions));
CliOption providedInCliOpt = new CliOption(PROVIDED_IN,
"Use this property to provide Injectables in wanted level.").defaultValue("root");
Map<String, String> providedInOptions = new HashMap<>();
providedInOptions.put(PROVIDED_IN_LEVEL.none.toString(), "No providedIn)");
providedInOptions.put(PROVIDED_IN_LEVEL.root.toString(), "The application-level injector in most apps.");
providedInOptions.put(PROVIDED_IN_LEVEL.platform.toString(), "A special singleton platform injector shared by all applications on the page.");
providedInOptions.put(PROVIDED_IN_LEVEL.any.toString(), "Provides a unique instance in each lazy loaded module while all eagerly loaded modules share one instance.");
providedInCliOpt.setEnum(providedInOptions);
this.cliOptions.add(providedInCliOpt);
this.cliOptions.add(new CliOption(API_MODULE_PREFIX, "The prefix of the generated ApiModule."));
this.cliOptions.add(new CliOption(CONFIGURATION_PREFIX, "The prefix of the generated Configuration."));
this.cliOptions.add(new CliOption(SERVICE_SUFFIX, "The suffix of the generated service.").defaultValue(this.serviceSuffix));
this.cliOptions.add(new CliOption(SERVICE_FILE_SUFFIX, "The suffix of the file of the generated service (service<suffix>.ts).").defaultValue(this.serviceFileSuffix));
this.cliOptions.add(new CliOption(MODEL_SUFFIX, "The suffix of the generated model."));
this.cliOptions.add(new CliOption(MODEL_FILE_SUFFIX, "The suffix of the file of the generated model (model<suffix>.ts)."));
this.cliOptions.add(new CliOption(FILE_NAMING, "Naming convention for the output files: 'camelCase', 'kebab-case'.").defaultValue(this.fileNaming));
this.cliOptions.add(new CliOption(STRING_ENUMS, STRING_ENUMS_DESC).defaultValue(String.valueOf(this.stringEnums)));
this.cliOptions.add(new CliOption(QUERY_PARAM_OBJECT_FORMAT, "The format for query param objects: 'dot', 'json', 'key'.").defaultValue(this.queryParamObjectFormat.name()));
}
@Override
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) {
codegenModel.additionalPropertiesType = getTypeDeclaration(getAdditionalProperties(schema));
addImport(codegenModel, codegenModel.additionalPropertiesType);
}
@Override
public String getName() {
return "typescript-koa-server";
}
@Override
public String getHelp() {
return "Generates a TypeScript Koa (2.x) server.";
}
@Override
public void processOpts() {
super.processOpts();
supportingFiles.add(new SupportingFile("env.example.mustache", "", ".env.example"));
supportingFiles.add(new SupportingFile("jest.config.js.mustache", "", ".jest.config.js"));
supportingFiles.add(new SupportingFile("app.ts.mustache", "", "app.ts"));
supportingFiles.add(new SupportingFile("build.js.mustache", "", "build.js"));
supportingFiles.add(new SupportingFile("docker-compose.mustache", "", "docker-compose.yml"));
supportingFiles.add(new SupportingFile("nodemon.mustache", "", "nodemon.json"));
supportingFiles.add(new SupportingFile("package.mustache", "", "package.json"));
supportingFiles.add(new SupportingFile("tsconfig.mustache", "", "tsconfig.json"));
// app/session folder
supportingFiles.add(new SupportingFile("sessions.service.ts.mustache", "app" + File.separator + "services", "sessions.service.ts"));
supportingFiles.add(new SupportingFile("sessions.index.ts.mustache", "app" + File.separator + "ervices", "index.ts"));
// app/helpers folder
supportingFiles.add(new SupportingFile("client.ts.mustache", "app" + File.separator + "helpers", "client.ts"));
// app/jobs folder
supportingFiles.add(new SupportingFile("jobs.README.mustache", "app" + File.separator + "jobs", "README.md"));
// app/controllers
supportingFiles.add(new SupportingFile("index.ts.mustache", "app" + File.separator + "controllers", "index.ts"));
supportingFiles.add(new SupportingFile("sessions.controller.ts.mustache", "app" + File.separator + "controllers", "sessions.controller.ts"));
// app/controllers/__tests__
supportingFiles.add(new SupportingFile("session.test.js.mustache", "app" + File.separator + "controllers" + File.separator + "__tests__", "session.test.js"));
// configs
supportingFiles.add(new SupportingFile("application.ts.mustache", "configs", "application.ts"));
supportingFiles.add(new SupportingFile("bootstrap.ts.mustache", "configs", "bootstrap.ts"));
supportingFiles.add(new SupportingFile("interceptors.ts.mustache", "configs", "interceptors.ts"));
supportingFiles.add(new SupportingFile("koa.middlewares.ts.mustache", "configs", "koa.middlewares.ts"));
supportingFiles.add(new SupportingFile("routing.middlewares.ts.mustache", "configs", "routing.middlewares.ts"));
supportingFiles.add(new SupportingFile("routing.options.ts.mustache", "configs", "routing.options.ts"));
supportingFiles.add(new SupportingFile("utils.ts.mustache", "configs", "utils.ts"));
// configs/constants
supportingFiles.add(new SupportingFile("development.ts.mustache", "configs" + File.separator + "constants", "development.ts"));
supportingFiles.add(new SupportingFile("envs.ts.mustache", "configs" + File.separator + "constants", "envs.ts"));
supportingFiles.add(new SupportingFile("configs.constants.index.ts.mustache", "configs" + File.separator + "constants", "index.ts"));
supportingFiles.add(new SupportingFile("production.ts.mustache", "configs" + File.separator + "constants", "production.ts"));
supportingFiles.add(new SupportingFile("staging.ts.mustache", "configs" + File.separator + "constants", "staging.ts"));
// prisma
supportingFiles.add(new SupportingFile("schema.prisma.mustache", "prisma", "schema.prisma"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
if (additionalProperties.containsKey(CONFIGURATION_PREFIX)) {
String configurationPrefix = additionalProperties.get(CONFIGURATION_PREFIX).toString();
validateClassPrefixArgument("Configuration", configurationPrefix);
additionalProperties.put("configurationClassName", configurationPrefix + "Configuration");
additionalProperties.put("configurationParametersInterfaceName", configurationPrefix + "ConfigurationParameters");
} else {
additionalProperties.put("configurationClassName", "Configuration");
additionalProperties.put("configurationParametersInterfaceName", "ConfigurationParameters");
}
}
private String getIndexDirectory() {
String indexPackage = modelPackage.substring(0, Math.max(0, modelPackage.lastIndexOf('.')));
return indexPackage.replace('.', File.separatorChar);
}
public void setStringEnums(boolean value) {
stringEnums = value;
}
public Boolean getStringEnums() {
return stringEnums;
}
public boolean getQueryParamObjectFormatDot() {
return QUERY_PARAM_OBJECT_FORMAT_TYPE.dot.equals(queryParamObjectFormat);
}
public boolean getQueryParamObjectFormatJson() {
return QUERY_PARAM_OBJECT_FORMAT_TYPE.json.equals(queryParamObjectFormat);
}
public boolean getQueryParamObjectFormatKey() {
return QUERY_PARAM_OBJECT_FORMAT_TYPE.key.equals(queryParamObjectFormat);
}
@Override
public boolean isDataTypeFile(final String dataType) {
return "Blob".equals(dataType);
}
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isFileSchema(p)) {
return "Blob";
} else {
return super.getTypeDeclaration(p);
}
}
private String applyLocalTypeMapping(String type) {
if (typeMapping.containsKey(type)) {
type = typeMapping.get(type);
}
return type;
}
@Override
public void postProcessParameter(CodegenParameter parameter) {
super.postProcessParameter(parameter);
parameter.dataType = applyLocalTypeMapping(parameter.dataType);
}
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap operations, List<ModelMap> allModels) {
OperationMap objs = operations.getOperations();
// Add filename information for api imports
objs.put("apiFilename", getApiFilenameFromClassname(objs.getClassname()));
List<CodegenOperation> ops = objs.getOperation();
boolean hasSomeFormParams = false;
boolean hasSomeEncodableParams = false;
for (CodegenOperation op : ops) {
if (op.getHasFormParams()) {
hasSomeFormParams = true;
}
op.httpMethod = op.httpMethod.toLowerCase(Locale.ENGLISH);
// Prep a string buffer where we're going to set up our new version of the string.
StringBuilder pathBuffer = new StringBuilder();
ParameterExpander paramExpander = new ParameterExpander(op, this::toParamName);
int insideCurly = 0;
// Iterate through existing string, one character at a time.
for (int i = 0; i < op.path.length(); i++) {
switch (op.path.charAt(i)) {
case '{':
// We entered curly braces, so track that.
insideCurly++;
break;
case '}':
// We exited curly braces, so track that.
insideCurly--;
pathBuffer.append(paramExpander.buildPathEntry());
hasSomeEncodableParams = true;
break;
default:
char nextChar = op.path.charAt(i);
if (insideCurly > 0) {
paramExpander.appendToParameterName(nextChar);
} else {
pathBuffer.append(nextChar);
}
break;
}
}
// Overwrite path to TypeScript template string, after applying everything we just did.
op.path = pathBuffer.toString();
}
operations.put("hasSomeFormParams", hasSomeFormParams);
operations.put("hasSomeEncodableParams", hasSomeEncodableParams);
// Add additional filename information for model imports in the services
List<Map<String, String>> imports = operations.getImports();
for (Map<String, String> im : imports) {
// This property is not used in the templates any more, subject for removal
im.put("filename", im.get("import"));
im.put("classname", im.get("classname"));
}
return operations;
}
@Override
public ModelsMap postProcessModels(ModelsMap objs) {
ModelsMap result = super.postProcessModels(objs);
return postProcessModelsEnum(result);
}
@Override
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
Map<String, ModelsMap> result = super.postProcessAllModels(objs);
for (ModelsMap entry : result.values()) {
for (ModelMap mo : entry.getModels()) {
CodegenModel cm = mo.getModel();
if (taggedUnions) {
mo.put(TAGGED_UNIONS, true);
if (cm.discriminator != null && cm.children != null) {
for (CodegenModel child : cm.children) {
cm.imports.add(child.classname);
setChildDiscriminatorValue(cm, child);
}
}
// with tagged union, a child model doesn't extend the parent (all properties are just copied over)
// it means we don't need to import that parent any more
if (cm.parent != null) {
cm.imports.remove(cm.parent);
// however, it's possible that the child model contains a recursive reference to the parent
// in order to support this case, we update the list of imports from properties once again
for (CodegenProperty cp : cm.allVars) {
addImportsForPropertyType(cm, cp);
}
removeSelfReferenceImports(cm);
}
}
// Add additional filename information for imports
Set<String> parsedImports = parseImports(cm);
mo.put("tsImports", toTsImports(cm, parsedImports));
}
}
return result;
}
private void setChildDiscriminatorValue(CodegenModel parent, CodegenModel child) {
if (child.vendorExtensions.isEmpty() ||
!child.vendorExtensions.containsKey("x-discriminator-value")
) {
for (CodegenProperty prop : child.allVars) {
if (prop.baseName.equals(parent.discriminator.getPropertyName())) {
for (CodegenDiscriminator.MappedModel mappedModel : parent.discriminator.getMappedModels()) {
if (mappedModel.getModelName().equals(child.classname)) {
prop.discriminatorValue = mappedModel.getMappingName();
}
}
}
}
}
}
/**
* Parse imports
*/
private Set<String> parseImports(CodegenModel cm) {
Set<String> newImports = new HashSet<>();
if (cm.imports.size() > 0) {
for (String name : cm.imports) {
if (name.indexOf(" | ") >= 0) {
String[] parts = name.split(" \\| ");
Collections.addAll(newImports, parts);
} else {
newImports.add(name);
}
}
}
return newImports;
}
private List<Map<String, String>> toTsImports(CodegenModel cm, Set<String> imports) {
List<Map<String, String>> tsImports = new ArrayList<>();
for (String im : imports) {
if (!im.equals(cm.classname)) {
HashMap<String, String> tsImport = new HashMap<>();
// TVG: This is used as class name in the import statements of the model file
tsImport.put("classname", im);
tsImport.put("filename", toModelFilename(removeModelPrefixSuffix(im)));
tsImports.add(tsImport);
}
}
return tsImports;
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultService";
}
return camelize(name) + serviceSuffix;
}
@Override
public String toApiFilename(String name) {
if (name.length() == 0) {
return "default.service";
}
return this.convertUsingFileNamingConvention(name) + serviceFileSuffix;
}
@Override
public String toApiImport(String name) {
if (importMapping.containsKey(name)) {
return importMapping.get(name);
}
return apiPackage() + "/" + toApiFilename(name);
}
@Override
public String toModelFilename(String name) {
if (importMapping.containsKey(name)) {
return importMapping.get(name);
}
return DEFAULT_IMPORT_PREFIX + this.convertUsingFileNamingConvention(super.toModelFilename(name)) + modelFileSuffix;
}
@Override
public String toModelImport(String name) {
if (importMapping.containsKey(name)) {
return importMapping.get(name);
}
return DEFAULT_MODEL_IMPORT_DIRECTORY_PREFIX + modelPackage() + "/" + toModelFilename(name).substring(DEFAULT_IMPORT_PREFIX.length());
}
public String getNpmRepository() {
return npmRepository;
}
public void setNpmRepository(String npmRepository) {
this.npmRepository = npmRepository;
}
private boolean getUseSingleRequestParameter() {
return useSingleRequestParameter;
}
private void setUseSingleRequestParameter(boolean useSingleRequestParameter) {
this.useSingleRequestParameter = useSingleRequestParameter;
}
private String getApiFilenameFromClassname(String classname) {
String name = classname.substring(0, classname.length() - serviceSuffix.length());
return toApiFilename(name);
}
@Override
public String toModelName(String name) {
name = addSuffix(name, modelSuffix);
return super.toModelName(name);
}
public String removeModelPrefixSuffix(String name) {
String result = name;
if (modelSuffix.length() > 0 && result.endsWith(modelSuffix)) {
result = result.substring(0, result.length() - modelSuffix.length());
}
String prefix = capitalize(this.modelNamePrefix);
String suffix = capitalize(this.modelNameSuffix);
if (prefix.length() > 0 && result.startsWith(prefix)) {
result = result.substring(prefix.length());
}
if (suffix.length() > 0 && result.endsWith(suffix)) {
result = result.substring(0, result.length() - suffix.length());
}
return result;
}
/**
* Validates that the given string value only contains '-', '.' and alpha numeric characters.
* Throws an IllegalArgumentException, if the string contains any other characters.
*
* @param argument The name of the argument being validated. This is only used for displaying an error message.
* @param value The value that is being validated.
*/
private void validateFileSuffixArgument(String argument, String value) {
if (!value.matches(FILE_NAME_SUFFIX_PATTERN)) {
throw new IllegalArgumentException(
String.format(Locale.ROOT, "%s file suffix only allows '.', '-' and alphanumeric characters.", argument)
);
}
}
/**
* Validates that the given string value only contains alpha numeric characters.
* Throws an IllegalArgumentException, if the string contains any other characters.
*
* @param argument The name of the argument being validated. This is only used for displaying an error message.
* @param value The value that is being validated.
*/
private void validateClassPrefixArgument(String argument, String value) {
if (!value.matches(CLASS_NAME_PREFIX_PATTERN)) {
throw new IllegalArgumentException(
String.format(Locale.ROOT, "%s class prefix only allows alphanumeric characters.", argument)
);
}
}
/**
* Validates that the given string value only contains alpha numeric characters.
* Throws an IllegalArgumentException, if the string contains any other characters.
*
* @param argument The name of the argument being validated. This is only used for displaying an error message.
* @param value The value that is being validated.
*/
private void validateClassSuffixArgument(String argument, String value) {
if (!value.matches(CLASS_NAME_SUFFIX_PATTERN)) {
throw new IllegalArgumentException(
String.format(Locale.ROOT, "%s class suffix only allows alphanumeric characters.", argument)
);
}
}
/**
* Set the query param object format.
*
* @param format the query param object format to use
*/
public void setQueryParamObjectFormat(String format) {
try {
queryParamObjectFormat = QUERY_PARAM_OBJECT_FORMAT_TYPE.valueOf(format);
} catch (IllegalArgumentException e) {
String values = Stream.of(QUERY_PARAM_OBJECT_FORMAT_TYPE.values())
.map(value -> "'" + value.name() + "'")
.collect(Collectors.joining(", "));
String msg = String.format(Locale.ROOT, "Invalid query param object format '%s'. Must be one of %s.", format, values);
throw new IllegalArgumentException(msg);
}
}
/**
* Set the file naming type.
*
* @param fileNaming the file naming to use
*/
private void setFileNaming(String fileNaming) {
if ("camelCase".equals(fileNaming) || "kebab-case".equals(fileNaming)) {
this.fileNaming = fileNaming;
} else {
throw new IllegalArgumentException("Invalid file naming '" +
fileNaming + "'. Must be 'camelCase' or 'kebab-case'");
}
}
/**
* Converts the original name according to the current <code>fileNaming</code> strategy.
*
* @param originalName the original name to transform
* @return the transformed name
*/
private String convertUsingFileNamingConvention(String originalName) {
String name = this.removeModelPrefixSuffix(originalName);
if ("kebab-case".equals(fileNaming)) {
name = dashize(underscore(name));
} else {
name = camelize(name, LOWERCASE_FIRST_LETTER);
}
return name;
}
/**
* Set the Injectable level
*
* @param level the wanted level
*/
public void setProvidedIn(String level) {
try {
providedIn = PROVIDED_IN_LEVEL.valueOf(level);
} catch (IllegalArgumentException e) {
String values = Stream.of(PROVIDED_IN_LEVEL.values())
.map(value -> "'" + value.name() + "'")
.collect(Collectors.joining(", "));
String msg = String.format(Locale.ROOT, "Invalid providedIn level '%s'. Must be one of %s.", level, values);
throw new IllegalArgumentException(msg);
}
}
/**
*
*/
private boolean getIsProvidedInNone() {
return PROVIDED_IN_LEVEL.none.equals(providedIn);
}
}

View File

@@ -124,7 +124,7 @@ public interface {{classname}} extends ApiClient.Api {
"{{baseName}}: {{=<% %>=}}{<%paramName%>}<%={{ }}=%>"{{^-last}},
{{/-last}}{{/headerParams}}
})
{{#returnType}}{{{.}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}({{#allParams}}{{^isQueryParam}}{{^isBodyParam}}{{^isFormParam}}{{^legacyDates}}@Param("{{paramName}}") {{/legacyDates}}{{#legacyDates}}@Param(value="{{paramName}}", expander=ParamExpander.class) {{/legacyDates}}{{/isFormParam}}{{#isFormParam}}@Param("{{baseName}}") {{/isFormParam}}{{/isBodyParam}}{{{dataType}}} {{paramName}}, {{/isQueryParam}}{{/allParams}}@QueryMap(encoded=true) {{operationIdCamelCase}}QueryParams queryParams);
{{#returnType}}{{{.}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}({{#allParams}}{{^isQueryParam}}{{^isBodyParam}}{{^isFormParam}}{{^legacyDates}}@Param("{{paramName}}") {{/legacyDates}}{{#legacyDates}}@Param(value="{{paramName}}", expander=ParamExpander.class) {{/legacyDates}}{{/isFormParam}}{{#isFormParam}}@Param("{{baseName}}") {{/isFormParam}}{{/isBodyParam}}{{{dataType}}} {{paramName}}, {{/isQueryParam}}{{/allParams}}@QueryMap(encoded=true) Map<String, Object> queryParams);
/**
* {{summary}}
@@ -164,7 +164,7 @@ public interface {{classname}} extends ApiClient.Api {
"{{baseName}}: {{=<% %>=}}{<%paramName%>}<%={{ }}=%>"{{^-last}},
{{/-last}}{{/headerParams}}
})
ApiResponse<{{#returnType}}{{{.}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{nickname}}WithHttpInfo({{#allParams}}{{^isQueryParam}}{{^isBodyParam}}{{^isFormParam}}{{^legacyDates}}@Param("{{paramName}}") {{/legacyDates}}{{#legacyDates}}@Param(value="{{paramName}}", expander=ParamExpander.class) {{/legacyDates}}{{/isFormParam}}{{#isFormParam}}@Param("{{baseName}}") {{/isFormParam}}{{/isBodyParam}}{{{dataType}}} {{paramName}}, {{/isQueryParam}}{{/allParams}}@QueryMap(encoded=true) {{operationIdCamelCase}}QueryParams queryParams);
ApiResponse<{{#returnType}}{{{.}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{nickname}}WithHttpInfo({{#allParams}}{{^isQueryParam}}{{^isBodyParam}}{{^isFormParam}}{{^legacyDates}}@Param("{{paramName}}") {{/legacyDates}}{{#legacyDates}}@Param(value="{{paramName}}", expander=ParamExpander.class) {{/legacyDates}}{{/isFormParam}}{{#isFormParam}}@Param("{{baseName}}") {{/isFormParam}}{{/isBodyParam}}{{{dataType}}} {{paramName}}, {{/isQueryParam}}{{/allParams}}@QueryMap(encoded=true) Map<String, Object> queryParams);
/**

View File

@@ -674,16 +674,18 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
Map<String,Object> uriParams = new HashMap<>();
uriParams.putAll(pathParams);
String finalUri = path;
String queryUri = null;
if (queryParams != null && !queryParams.isEmpty()) {
//Include queryParams in uriParams taking into account the paramName
String queryUri = generateQueryUri(queryParams, uriParams);
//Append to finalUri the templatized query string like "?param1={param1Value}&.......
finalUri += "?" + queryUri;
String query = generateQueryUri(queryParams, uriParams);
queryUri = expandPath("?" + query, uriParams).substring(1); //exclude the '?'
//queryUri is the templatized query string like "?param1={param1Value}&.......
}
String expandedPath = this.expandPath(finalUri, uriParams);
final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(basePath).path(expandedPath);
String expandedPath = this.expandPath(path, uriParams);
final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(basePath)
.path(expandedPath)
.query(queryUri);
URI uri;
try {

View File

@@ -11,7 +11,7 @@
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
{{#springDocDocumentationProvider}}
<springdoc.version>2.0.2</springdoc.version>
<springdoc.version>2.0.0-M3</springdoc.version>
{{/springDocDocumentationProvider}}
{{^springDocDocumentationProvider}}
{{#swagger2AnnotationLibrary}}
@@ -19,7 +19,7 @@
{{/swagger2AnnotationLibrary}}
{{/springDocDocumentationProvider}}
{{#useSwaggerUI}}
<swagger-ui.version>4.15.5</swagger-ui.version>
<swagger-ui.version>4.8.1</swagger-ui.version>
{{/useSwaggerUI}}
{{#virtualService}}
<virtualan.version>2.5.2</virtualan.version>
@@ -36,7 +36,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<version>3.0.0-M3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
{{/parentOverridden}}

View File

@@ -14,7 +14,7 @@
<springfox.version>2.9.2</springfox.version>
{{/springFoxDocumentationProvider}}
{{#springDocDocumentationProvider}}
<springdoc.version>1.6.14</springdoc.version>
<springdoc.version>1.6.8</springdoc.version>
{{/springDocDocumentationProvider}}
{{^springFoxDocumentationProvider}}
{{^springDocDocumentationProvider}}
@@ -30,7 +30,7 @@
<virtualan.version>2.5.2</virtualan.version>
{{/virtualService}}
{{#useSwaggerUI}}
<swagger-ui.version>4.15.5</swagger-ui.version>
<swagger-ui.version>4.10.3</swagger-ui.version>
{{/useSwaggerUI}}
</properties>
{{#parentOverridden}}
@@ -44,7 +44,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>{{#springFoxDocumentationProvider}}2.5.14{{/springFoxDocumentationProvider}}{{^springFoxDocumentationProvider}}2.7.6{{/springFoxDocumentationProvider}}</version>
<version>{{#springFoxDocumentationProvider}}2.5.14{{/springFoxDocumentationProvider}}{{^springFoxDocumentationProvider}}2.7.0{{/springFoxDocumentationProvider}}</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
{{/parentOverridden}}

View File

@@ -11,7 +11,7 @@
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
{{#springDocDocumentationProvider}}
<springdoc.version>2.0.2</springdoc.version>
<springdoc.version>2.0.0-M3</springdoc.version>
{{/springDocDocumentationProvider}}
{{^springDocDocumentationProvider}}
{{#swagger2AnnotationLibrary}}
@@ -30,7 +30,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<version>3.0.0-M4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
{{/parentOverridden}}
@@ -53,7 +53,7 @@
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>2022.0.0</version>
<version>2022.0.0-M3</version>
<type>pom</type>
<scope>import</scope>
</dependency>

View File

@@ -14,7 +14,7 @@
<springfox.version>2.9.2</springfox.version>
{{/springFoxDocumentationProvider}}
{{#springDocDocumentationProvider}}
<springdoc.version>1.6.14</springdoc.version>
<springdoc.version>1.6.8</springdoc.version>
{{/springDocDocumentationProvider}}
{{^springFoxDocumentationProvider}}
{{^springDocDocumentationProvider}}
@@ -38,7 +38,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.6</version>
<version>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
{{/parentOverridden}}
@@ -52,7 +52,7 @@
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>2021.0.5</version>
<version>2021.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>

View File

@@ -133,7 +133,6 @@ org.openapitools.codegen.languages.TypeScriptAxiosClientCodegen
org.openapitools.codegen.languages.TypeScriptFetchClientCodegen
org.openapitools.codegen.languages.TypeScriptInversifyClientCodegen
org.openapitools.codegen.languages.TypeScriptJqueryClientCodegen
org.openapitools.codegen.languages.TypeScriptKoaServerCodegen
org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen
org.openapitools.codegen.languages.TypeScriptNodeClientCodegen
org.openapitools.codegen.languages.TypeScriptReduxQueryClientCodegen

View File

@@ -796,14 +796,14 @@ class MediaType:
@dataclass
class ApiResponse:
response: urllib3.HTTPResponse
body: typing.Union[Unset, Schema] = unset
headers: typing.Union[Unset, typing.Dict[str, Schema]] = unset
body: typing.Union[Unset, Schema]
headers: typing.Union[Unset, typing.List[HeaderParameter]]
def __init__(
self,
response: urllib3.HTTPResponse,
body: typing.Union[Unset, Schema] = unset,
headers: typing.Union[Unset, typing.Dict[str, Schema]] = unset
body: typing.Union[Unset, typing.Type[Schema]],
headers: typing.Union[Unset, typing.List[HeaderParameter]]
):
"""
pycharm needs this to prevent 'Unexpected argument' warnings

View File

@@ -70,17 +70,13 @@ require '{{{gemName}}}'
config.username = 'YOUR_USERNAME'
config.password = 'YOUR_PASSWORD'{{/isBasicBasic}}{{#isBasicBearer}}
# Configure Bearer authorization{{#bearerFormat}} ({{{.}}}){{/bearerFormat}}: {{{name}}}
config.access_token = 'YOUR_BEARER_TOKEN'
# Configure a proc to get access tokens in lieu of the static access_token configuration
config.access_token_getter = -> { 'YOUR TOKEN GETTER PROC' } {{/isBasicBearer}}{{/isBasic}}{{#isApiKey}}
config.access_token = 'YOUR_BEARER_TOKEN'{{/isBasicBearer}}{{/isBasic}}{{#isApiKey}}
# Configure API key authorization: {{{name}}}
config.api_key['{{{name}}}'] = 'YOUR API KEY'
# Uncomment the following line to set a prefix for the API key, e.g. 'Bearer' (defaults to nil)
# config.api_key_prefix['{{{name}}}'] = 'Bearer'{{/isApiKey}}{{#isOAuth}}
# Configure OAuth2 access token for authorization: {{{name}}}
config.access_token = 'YOUR ACCESS TOKEN'
# Configure a proc to get access tokens in lieu of the static access_token configuration
config.access_token_getter = -> { 'YOUR TOKEN GETTER PROC' } {{/isOAuth}}
config.access_token = 'YOUR ACCESS TOKEN'{{/isOAuth}}
{{/authMethods}}end
{{/hasAuthMethods}}

View File

@@ -54,11 +54,6 @@ module {{moduleName}}
# Defines the access token (Bearer) used with OAuth2.
attr_accessor :access_token
# Defines a Proc used to fetch or refresh access tokens (Bearer) used with OAuth2.
# Overrides the access_token if set
# @return [Proc]
attr_accessor :access_token_getter
# Set this to enable/disable debugging. When enabled (set to true), HTTP request/response
# details will be logged with `logger.debug` (see the `logger` attribute).
# Default to false.
@@ -183,12 +178,6 @@ module {{moduleName}}
end
end
# Gets access_token using access_token_getter or uses the static access_token
def access_token_with_refresh
return access_token if access_token_getter.nil?
access_token_getter.call
end
# Gets Basic Auth token string
def basic_auth_token
'Basic ' + ["#{username}:#{password}"].pack('m').delete("\r\n")
@@ -226,7 +215,7 @@ module {{moduleName}}
format: '{{{.}}}',
{{/bearerFormat}}
key: 'Authorization',
value: "Bearer #{access_token_with_refresh}"
value: "Bearer #{access_token}"
},
{{/isBasicBearer}}
{{/isBasic}}
@@ -236,7 +225,7 @@ module {{moduleName}}
type: 'oauth2',
in: 'header',
key: 'Authorization',
value: "Bearer #{access_token_with_refresh}"
value: "Bearer #{access_token}"
},
{{/isOAuth}}
{{/authMethods}}

View File

@@ -1,126 +0,0 @@
// Validation.swift
//
// Generated by openapi-generator
// https://openapi-generator.tech
//
import Foundation
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} struct StringRule {
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var minLength: Int?
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var maxLength: Int?
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var pattern: String?
}
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} struct NumericRule<T: Comparable & Numeric> {
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var minimum: T?
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var exclusiveMinimum = false
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var maximum: T?
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var exclusiveMaximum = false
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var multipleOf: T?
}
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} enum StringValidationErrorKind: Error {
case minLength, maxLength, pattern
}
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} enum NumericValidationErrorKind: Error {
case minimum, maximum, multipleOf
}
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} struct ValidationError<T: Error & Hashable>: Error {
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} fileprivate(set) var kinds: Set<T>
}
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} struct Validator {
/// Validate a string against a rule.
/// - Parameter string: The String you wish to validate.
/// - Parameter rule: The StringRule you wish to use for validation.
/// - Returns: A validated string.
/// - Throws: `ValidationError<StringValidationErrorKind>` if the string is invalid against the rule,
/// `NSError` if the rule.pattern is invalid.
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} static func validate(_ string: String, against rule: StringRule) throws -> String {
var error = ValidationError<StringValidationErrorKind>(kinds: [])
if let minLength = rule.minLength, !(minLength <= string.count) {
error.kinds.insert(.minLength)
}
if let maxLength = rule.maxLength, !(string.count <= maxLength) {
error.kinds.insert(.maxLength)
}
if let pattern = rule.pattern {
let matches = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)
.matches(in: string, range: .init(location: 0, length: string.utf16.count))
if matches.isEmpty {
error.kinds.insert(.pattern)
}
}
guard error.kinds.isEmpty else {
throw error
}
return string
}
/// Validate a integer against a rule.
/// - Parameter numeric: The integer you wish to validate.
/// - Parameter rule: The NumericRule you wish to use for validation.
/// - Returns: A validated integer.
/// - Throws: `ValidationError<NumericValidationErrorKind>` if the numeric is invalid against the rule.
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} static func validate<T: Comparable & BinaryInteger>(_ numeric: T, against rule: NumericRule<T>) throws -> T {
var error = ValidationError<NumericValidationErrorKind>(kinds: [])
if let minium = rule.minimum {
if !rule.exclusiveMinimum, !(minium <= numeric) {
error.kinds.insert(.minimum)
}
if rule.exclusiveMinimum, !(minium < numeric) {
error.kinds.insert(.minimum)
}
}
if let maximum = rule.maximum {
if !rule.exclusiveMaximum, !(numeric <= maximum) {
error.kinds.insert(.maximum)
}
if rule.exclusiveMaximum, !(numeric < maximum) {
error.kinds.insert(.maximum)
}
}
if let multipleOf = rule.multipleOf, !numeric.isMultiple(of: multipleOf) {
error.kinds.insert(.multipleOf)
}
guard error.kinds.isEmpty else {
throw error
}
return numeric
}
/// Validate a fractional number against a rule.
/// - Parameter numeric: The fractional number you wish to validate.
/// - Parameter rule: The NumericRule you wish to use for validation.
/// - Returns: A validated fractional number.
/// - Throws: `ValidationError<NumericValidationErrorKind>` if the numeric is invalid against the rule.
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} static func validate<T: Comparable & FloatingPoint>(_ numeric: T, against rule: NumericRule<T>) throws -> T {
var error = ValidationError<NumericValidationErrorKind>(kinds: [])
if let minium = rule.minimum {
if !rule.exclusiveMinimum, !(minium <= numeric) {
error.kinds.insert(.minimum)
}
if rule.exclusiveMinimum, !(minium < numeric) {
error.kinds.insert(.minimum)
}
}
if let maximum = rule.maximum {
if !rule.exclusiveMaximum, !(numeric <= maximum) {
error.kinds.insert(.maximum)
}
if rule.exclusiveMaximum, !(numeric < maximum) {
error.kinds.insert(.maximum)
}
}
if let multipleOf = rule.multipleOf, numeric.remainder(dividingBy: multipleOf) != 0 {
error.kinds.insert(.multipleOf)
}
guard error.kinds.isEmpty else {
throw error
}
return numeric
}
}

View File

@@ -8,18 +8,6 @@
{{/isEnum}}
{{/allVars}}
{{#allVars}}
{{#validatable}}
{{#hasValidation}}
{{#isString}}
static let {{{name}}}Rule = StringRule(minLength: {{#minLength}}{{{.}}}{{/minLength}}{{^minLength}}nil{{/minLength}}, maxLength: {{#maxLength}}{{{.}}}{{/maxLength}}{{^maxLength}}nil{{/maxLength}}, pattern: {{#pattern}}"{{{.}}}"{{/pattern}}{{^pattern}}nil{{/pattern}})
{{/isString}}
{{#isNumeric}}
static let {{{name}}}Rule = NumericRule<{{{dataType}}}>(minimum: {{#minimum}}{{{.}}}{{/minimum}}{{^minimum}}nil{{/minimum}}, exclusiveMinimum: {{#exclusiveMinimum}}true{{/exclusiveMinimum}}{{^exclusiveMinimum}}false{{/exclusiveMinimum}}, maximum: {{#maximum}}{{{.}}}{{/maximum}}{{^maximum}}nil{{/maximum}}, exclusiveMaximum: {{#exclusiveMaximum}}true{{/exclusiveMaximum}}{{^exclusiveMaximum}}false{{/exclusiveMaximum}}, multipleOf: {{#multipleOf}}{{{.}}}{{/multipleOf}}{{^multipleOf}}nil{{/multipleOf}})
{{/isNumeric}}
{{/hasValidation}}
{{/validatable}}
{{/allVars}}
{{#allVars}}
{{#isEnum}}
{{#description}}/** {{{.}}} */
{{/description}}{{#deprecated}}@available(*, deprecated, message: "This property is deprecated.")

View File

@@ -1,107 +0,0 @@
### koa-ts
The best practice of building Koa2 with TypeScript. [中文](/README_CN.md)
---
#### Usage
1. Run `npm init koa-ts`
2. Install dependencies: `yarn`
3. Rename `.env.example` to `.env`, and run `prisma db push` to synchronize the data model
4. Start the server: `yarn dev`. visit: http://127.0.0.1:3000/apis/sessions
> **(Optional)** the project has built-in a docker compose, run `yarn dev:db` to run database automatic.
---
#### Project Layout
```
├── app
│   ├── controllers --- server controllers
│   ├── helpers --- helper func (interceptor / error handler / validator...)
│   ├── jobs --- task (periodic task / trigger task / email server...)
│   ├── entities --- database entities/models
│   └── services --- adhesive controller and model
├── config
│   ├── constants --- environment variable
│  ├── koa.middlewares --- middlewares for Koa
│  ├── routing.middlewares --- middlewares for Routing Controller
│  ├── routing.options --- configs for Routing Controller
│   ├── bootstrap --- lifecycle
│   └── interceptors --- global interceptor
│   └── utils --- pure functions for help
└── test --- utils for testcase
├── .env --- environment file
```
---
#### Feature
- Separation configuration and business logic.
- Export scheme model and interface, follow style of TypeScript.
- Test cases and lint configuration.
- The best practice for Dependency Injection in Koa project.
- Get constraints on your data model with Prisma.
- TypeScript hotload.
---
#### Lifecycle
1. `app.ts` -> collect env vars `constants` -> collect env files `variables.env`
2. envs ready, call `bootstrap.before()`
3. lift `routing-controllers` -> lift Koa middlewares -> register `Container` for DI
4. start Koa &amp; invoke `bootstrap.after()` after startup
---
#### Databases
The project uses Prisma as the intelligent ORM tool by default. Supports `PostgreSQL`, `MySQL` and `SQLite`.
- You can change the data type and connection method in the `.env` file
- After each modification to file `/prisma/schema.prisma`, you need to run `prisma migrate dev` to migrate the database.
- After each modification to file `/prisma/schema.prisma`, you need to run `prisma generate` to sync types.
---
#### About Environments
When nodejs is running, `ENV` does not mean `NODE_ENV`:
- After NodeJS project is built, we always run it as `NODE_ENV=PRODUCTION`, which may affect some framework optimizations.
- `NODE_ENV` only identifies the NodeJS runtime, independent of the business.
- You should use `ENV` to identify the environment.
For the data settings of each environment, you can refer to the following:
- **Development Mode** (`ENV=development`): read configurations from `configs/constants/development.ts` file, but it will still be overwritten by `.env` file.
- **Production Mode** (`ENV=production`): read configurations from `configs/constants/production.ts` file, but it will still be overwritten by `.env` file.
---
#### Reference
- [routing-controllers](https://github.com/typestack/routing-controllers)
- [Prisma](https://www.prisma.io/docs/concepts)
---
#### LICENSE
This project is licensed under the MIT License. See the [LICENSE](./LICENSE) file for more info.

View File

@@ -1,37 +0,0 @@
import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core';
import { {{configurationClassName}} } from './configuration';
import { HttpClient } from '@angular/common/http';
{{#apiInfo}}
{{#apis}}
import { {{classname}} } from './{{importPath}}';
{{/apis}}
{{/apiInfo}}
@NgModule({
imports: [],
declarations: [],
exports: [],
providers: [{{#isProvidedInNone}}
{{#apiInfo}}{{#apis}}{{classname}}{{^-last}},
{{/-last}}{{/apis}}{{/apiInfo}} {{/isProvidedInNone}}]
})
export class {{apiModuleClassName}} {
public static forRoot(configurationFactory: () => {{configurationClassName}}): ModuleWithProviders{{#enforceGenericModuleWithProviders}}<{{apiModuleClassName}}>{{/enforceGenericModuleWithProviders}} {
return {
ngModule: {{apiModuleClassName}},
providers: [ { provide: {{configurationClassName}}, useFactory: configurationFactory } ]
};
}
constructor( @Optional() @SkipSelf() parentModule: {{apiModuleClassName}},
@Optional() http: HttpClient) {
if (parentModule) {
throw new Error('{{apiModuleClassName}} is already loaded. Import in your base AppModule only.');
}
if (!http) {
throw new Error('You need to import the HttpClientModule in your AppModule! \n' +
'See also https://github.com/angular/angular/issues/20575');
}
}
}

View File

@@ -1,404 +0,0 @@
{{>licenseInfo}}
/* tslint:disable:no-unused-variable member-ordering */
import { Inject, Injectable, Optional } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams,
HttpResponse, HttpEvent, HttpParameterCodec{{#httpContextInOptions}}, HttpContext {{/httpContextInOptions}}
} from '@angular/common/http';
import { CustomHttpParameterCodec } from '../encoder';
import { Observable } from 'rxjs';
{{#imports}}
// @ts-ignore
import { {{ classname }} } from '{{ filename }}';
{{/imports}}
// @ts-ignore
import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
import { {{configurationClassName}} } from '../configuration';
{{#withInterfaces}}
import {
{{classname}}Interface{{#useSingleRequestParameter}}{{#operations}}{{#operation}}{{#allParams.0}},
{{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams{{/allParams.0}}{{/operation}}{{/operations}}{{/useSingleRequestParameter}}
} from './{{classFilename}}Interface';
{{/withInterfaces}}
{{#operations}}
{{^withInterfaces}}
{{#useSingleRequestParameter}}
{{#operation}}
{{#allParams.0}}
export interface {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams {
{{#allParams}}
{{#description}}/** {{.}} */
{{/description}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#isNullable}} | null{{/isNullable}};
{{/allParams}}
}
{{/allParams.0}}
{{/operation}}
{{/useSingleRequestParameter}}
{{/withInterfaces}}
{{#description}}
/**
* {{&description}}
*/
{{/description}}
{{#isProvidedInNone}}
@Injectable()
{{/isProvidedInNone}}
{{^isProvidedInNone}}
@Injectable({
providedIn: '{{providedIn}}'
})
{{/isProvidedInNone}}
{{#withInterfaces}}
export class {{classname}} implements {{classname}}Interface {
{{/withInterfaces}}
{{^withInterfaces}}
export class {{classname}} {
{{/withInterfaces}}
protected basePath = '{{{basePath}}}';
public defaultHeaders = new HttpHeaders();
public configuration = new {{configurationClassName}}();
public encoder: HttpParameterCodec;
constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: {{configurationClassName}}) {
if (configuration) {
this.configuration = configuration;
}
if (typeof this.configuration.basePath !== 'string') {
if (Array.isArray(basePath) && basePath.length > 0) {
basePath = basePath[0];
}
if (typeof basePath !== 'string') {
basePath = this.basePath;
}
this.configuration.basePath = basePath;
}
this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
}
{{#hasSomeFormParams}}
/**
* @param consumes string[] mime-types
* @return true: consumes contains 'multipart/form-data', false: otherwise
*/
private canConsumeForm(consumes: string[]): boolean {
const form = 'multipart/form-data';
for (const consume of consumes) {
if (form === consume) {
return true;
}
}
return false;
}
{{/hasSomeFormParams}}
// @ts-ignore
private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams {
{{#isQueryParamObjectFormatJson}}
httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
{{/isQueryParamObjectFormatJson}}
{{^isQueryParamObjectFormatJson}}
if (typeof value === "object" && value instanceof Date === false) {
httpParams = this.addToHttpParamsRecursive(httpParams, value);
} else {
httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
}
{{/isQueryParamObjectFormatJson}}
return httpParams;
}
private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams {
if (value == null) {
return httpParams;
}
if (typeof value === "object") {
{{#isQueryParamObjectFormatJson}}
if (key != null) {
httpParams = httpParams.append(key, JSON.stringify(value));
} else {
throw Error("key may not be null if value is a QueryParamObject");
}
{{/isQueryParamObjectFormatJson}}
{{^isQueryParamObjectFormatJson}}
if (Array.isArray(value)) {
(value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key));
} else if (value instanceof Date) {
if (key != null) {
httpParams = httpParams.append(key, (value as Date).toISOString(){{^isDateTime}}.substr(0, 10){{/isDateTime}});
} else {
throw Error("key may not be null if value is Date");
}
} else {
Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive(
httpParams, value[k], key != null ? `${key}{{#isQueryParamObjectFormatDot}}.{{/isQueryParamObjectFormatDot}}{{#isQueryParamObjectFormatKey}}[{{/isQueryParamObjectFormatKey}}${k}{{#isQueryParamObjectFormatKey}}]{{/isQueryParamObjectFormatKey}}` : k));
}
{{/isQueryParamObjectFormatJson}}
} else if (key != null) {
httpParams = httpParams.append(key, value);
} else {
throw Error("key may not be null if value is not object or array");
}
return httpParams;
}
{{#operation}}
/**
{{#summary}}
* {{.}}
{{/summary}}
{{#notes}}
* {{.}}
{{/notes}}
{{^useSingleRequestParameter}}
{{#allParams}}
* @param {{paramName}} {{description}}
{{/allParams}}
{{/useSingleRequestParameter}}
{{#useSingleRequestParameter}}
{{#allParams.0}}
* @param requestParameters
{{/allParams.0}}
{{/useSingleRequestParameter}}
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
*/
public {{nickname}}({{^useSingleRequestParameter}}{{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams, {{/allParams.0}}{{/useSingleRequestParameter}}observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: {{#produces}}'{{mediaType}}'{{^-last}} | {{/-last}}{{/produces}}{{^produces}}undefined{{/produces}},{{#httpContextInOptions}} context?: HttpContext{{/httpContextInOptions}}}): Observable<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>;
public {{nickname}}({{^useSingleRequestParameter}}{{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams, {{/allParams.0}}{{/useSingleRequestParameter}}observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: {{#produces}}'{{mediaType}}'{{^-last}} | {{/-last}}{{/produces}}{{^produces}}undefined{{/produces}},{{#httpContextInOptions}} context?: HttpContext{{/httpContextInOptions}}}): Observable<HttpResponse<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>>;
public {{nickname}}({{^useSingleRequestParameter}}{{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams, {{/allParams.0}}{{/useSingleRequestParameter}}observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: {{#produces}}'{{mediaType}}'{{^-last}} | {{/-last}}{{/produces}}{{^produces}}undefined{{/produces}},{{#httpContextInOptions}} context?: HttpContext{{/httpContextInOptions}}}): Observable<HttpEvent<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>>;
public {{nickname}}({{^useSingleRequestParameter}}{{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams, {{/allParams.0}}{{/useSingleRequestParameter}}observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: {{#produces}}'{{mediaType}}'{{^-last}} | {{/-last}}{{/produces}}{{^produces}}undefined{{/produces}},{{#httpContextInOptions}} context?: HttpContext{{/httpContextInOptions}}}): Observable<any> {
{{#allParams}}
{{#useSingleRequestParameter}}
const {{paramName}} = requestParameters.{{paramName}};
{{/useSingleRequestParameter}}
{{#required}}
if ({{paramName}} === null || {{paramName}} === undefined) {
throw new Error('Required parameter {{paramName}} was null or undefined when calling {{nickname}}.');
}
{{/required}}
{{/allParams}}
{{#hasQueryParamsOrAuth}}
let localVarQueryParameters = new HttpParams({encoder: this.encoder});
{{#queryParams}}
{{#isArray}}
if ({{paramName}}) {
{{#isQueryParamObjectFormatJson}}
localVarQueryParameters = this.addToHttpParams(localVarQueryParameters,
<any>{{paramName}}, '{{baseName}}');
{{/isQueryParamObjectFormatJson}}
{{^isQueryParamObjectFormatJson}}
{{#isCollectionFormatMulti}}
{{paramName}}.forEach((element) => {
localVarQueryParameters = this.addToHttpParams(localVarQueryParameters,
<any>element, '{{baseName}}');
})
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
localVarQueryParameters = this.addToHttpParams(localVarQueryParameters,
[...{{paramName}}].join(COLLECTION_FORMATS['{{collectionFormat}}']), '{{baseName}}');
{{/isCollectionFormatMulti}}
{{/isQueryParamObjectFormatJson}}
}
{{/isArray}}
{{^isArray}}
if ({{paramName}} !== undefined && {{paramName}} !== null) {
localVarQueryParameters = this.addToHttpParams(localVarQueryParameters,
<any>{{paramName}}, '{{baseName}}');
}
{{/isArray}}
{{/queryParams}}
{{/hasQueryParamsOrAuth}}
let localVarHeaders = this.defaultHeaders;
{{#headerParams}}
{{#isArray}}
if ({{paramName}}) {
localVarHeaders = localVarHeaders.set('{{baseName}}', [...{{paramName}}].join(COLLECTION_FORMATS['{{collectionFormat}}']));
}
{{/isArray}}
{{^isArray}}
if ({{paramName}} !== undefined && {{paramName}} !== null) {
localVarHeaders = localVarHeaders.set('{{baseName}}', String({{paramName}}));
}
{{/isArray}}
{{/headerParams}}
{{#authMethods}}
{{#-first}}
let localVarCredential: string | undefined;
{{/-first}}
// authentication ({{name}}) required
localVarCredential = this.configuration.lookupCredential('{{name}}');
if (localVarCredential) {
{{#isApiKey}}
{{#isKeyInHeader}}
localVarHeaders = localVarHeaders.set('{{keyParamName}}', localVarCredential);
{{/isKeyInHeader}}
{{#isKeyInQuery}}
localVarQueryParameters = localVarQueryParameters.set('{{keyParamName}}', localVarCredential);
{{/isKeyInQuery}}
{{/isApiKey}}
{{#isBasic}}
{{#isBasicBasic}}
localVarHeaders = localVarHeaders.set('Authorization', 'Basic ' + localVarCredential);
{{/isBasicBasic}}
{{#isBasicBearer}}
localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential);
{{/isBasicBearer}}
{{/isBasic}}
{{#isOAuth}}
localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential);
{{/isOAuth}}
}
{{/authMethods}}
let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
if (localVarHttpHeaderAcceptSelected === undefined) {
// to determine the Accept header
const httpHeaderAccepts: string[] = [
{{#produces}}
'{{{mediaType}}}'{{^-last}},{{/-last}}
{{/produces}}
];
localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
}
if (localVarHttpHeaderAcceptSelected !== undefined) {
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
}
{{#httpContextInOptions}}
let localVarHttpContext: HttpContext | undefined = options && options.context;
if (localVarHttpContext === undefined) {
localVarHttpContext = new HttpContext();
}
{{/httpContextInOptions}}
{{#bodyParam}}
{{- duplicated below, don't forget to change}}
// to determine the Content-Type header
const consumes: string[] = [
{{#consumes}}
'{{{mediaType}}}'{{^-last}},{{/-last}}
{{/consumes}}
];
{{/bodyParam}}
{{#hasFormParams}}
{{^bodyParam}}
// to determine the Content-Type header
const consumes: string[] = [
{{#consumes}}
'{{{mediaType}}}'{{^-last}},{{/-last}}
{{/consumes}}
];
{{/bodyParam}}
{{/hasFormParams}}
{{#bodyParam}}
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected !== undefined) {
localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
}
{{/bodyParam}}
{{#hasFormParams}}
const canConsumeForm = this.canConsumeForm(consumes);
let localVarFormParams: { append(param: string, value: any): any; };
let localVarUseForm = false;
let localVarConvertFormParamsToString = false;
{{#formParams}}
{{#isFile}}
// use FormData to transmit files using content-type "multipart/form-data"
// see https://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data
localVarUseForm = canConsumeForm;
{{/isFile}}
{{/formParams}}
if (localVarUseForm) {
localVarFormParams = new FormData();
} else {
localVarFormParams = new HttpParams({encoder: this.encoder});
}
{{#formParams}}
{{#isArray}}
if ({{paramName}}) {
{{#isCollectionFormatMulti}}
{{paramName}}.forEach((element) => {
localVarFormParams = localVarFormParams.append('{{baseName}}', <any>element) as any || localVarFormParams;
})
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
if (localVarUseForm) {
{{paramName}}.forEach((element) => {
localVarFormParams = localVarFormParams.append('{{baseName}}', <any>element) as any || localVarFormParams;
})
} else {
localVarFormParams = localVarFormParams.append('{{baseName}}', [...{{paramName}}].join(COLLECTION_FORMATS['{{collectionFormat}}'])) as any || localVarFormParams;
}
{{/isCollectionFormatMulti}}
}
{{/isArray}}
{{^isArray}}
if ({{paramName}} !== undefined) {
localVarFormParams = localVarFormParams.append('{{baseName}}', {{^isModel}}<any>{{paramName}}{{/isModel}}{{#isModel}}localVarUseForm ? new Blob([JSON.stringify({{paramName}})], {type: 'application/json'}) : <any>{{paramName}}{{/isModel}}) as any || localVarFormParams;
}
{{/isArray}}
{{/formParams}}
{{/hasFormParams}}
{{^isResponseFile}}
let responseType_: 'text' | 'json' | 'blob' = 'json';
if (localVarHttpHeaderAcceptSelected) {
if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
responseType_ = 'text';
} else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
responseType_ = 'json';
} else {
responseType_ = 'blob';
}
}
{{/isResponseFile}}
let localVarPath = `{{{path}}}`;
return this.httpClient.request{{^isResponseFile}}<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>{{/isResponseFile}}('{{httpMethod}}', `${this.configuration.basePath}${localVarPath}`,
{
{{#httpContextInOptions}}
context: localVarHttpContext,
{{/httpContextInOptions}}
{{#bodyParam}}
body: {{paramName}},
{{/bodyParam}}
{{^bodyParam}}
{{#hasFormParams}}
body: localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams,
{{/hasFormParams}}
{{/bodyParam}}
{{#hasQueryParamsOrAuth}}
params: localVarQueryParameters,
{{/hasQueryParamsOrAuth}}
{{#isResponseFile}}
responseType: "blob",
{{/isResponseFile}}
{{^isResponseFile}}
responseType: <any>responseType_,
{{/isResponseFile}}
withCredentials: this.configuration.withCredentials,
headers: localVarHeaders,
observe: observe,
reportProgress: reportProgress
}
);
}
{{/operation}}}
{{/operations}}

View File

@@ -1,51 +0,0 @@
{{>licenseInfo}}
import { HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
{{#imports}}
import { {{classname}} } from '../model/models';
{{/imports}}
import { {{configurationClassName}} } from '../configuration';
{{#operations}}
{{#useSingleRequestParameter}}
{{#operation}}
{{#allParams.0}}
export interface {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams {
{{#allParams}}
{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#isNullable}} | null{{/isNullable}};
{{/allParams}}
}
{{/allParams.0}}
{{/operation}}
{{/useSingleRequestParameter}}
{{#description}}
/**
* {{&description}}
*/
{{/description}}
export interface {{classname}}Interface {
defaultHeaders: HttpHeaders;
configuration: {{configurationClassName}};
{{#operation}}
/**
* {{summary}}
* {{notes}}
{{^useSingleRequestParameter}}
{{#allParams}}* @param {{paramName}} {{description}}
{{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}* @param requestParameters
{{/allParams.0}}{{/useSingleRequestParameter}}{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}*/
{{nickname}}({{^useSingleRequestParameter}}{{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}{{/useSingleRequestParameter}}{{#useSingleRequestParameter}}{{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}RequestParams, {{/allParams.0}}{{/useSingleRequestParameter}}extraHttpRequestParams?: any): Observable<{{{returnType}}}{{^returnType}}{}{{/returnType}}>;
{{/operation}}
}
{{/operations}}

View File

@@ -1,12 +0,0 @@
{{#apiInfo}}
{{#apis}}
{{#operations}}
export * from './{{ classFilename }}';
import { {{ classname }} } from './{{ classFilename }}';
{{/operations}}
{{#withInterfaces}}
export * from './{{ classFilename }}Interface';
{{/withInterfaces}}
{{/apis}}
export const APIS = [{{#apis}}{{#operations}}{{ classname }}{{/operations}}{{^-last}}, {{/-last}}{{/apis}}];
{{/apiInfo}}

View File

@@ -1,17 +0,0 @@
import { Server } from 'http'
import { print } from 'configs/utils'
import CONSTANTS from 'configs/constants'
import createServer from 'configs/application'
import { bootstrapAfter } from 'configs/bootstrap'
module.exports = (async (): Promise<Server> => {
try {
const app = await createServer()
return app.listen(CONSTANTS.PORT, () => {
print.log(`server listening on ${CONSTANTS.PORT}, in ${CONSTANTS.ENV_LABEL} mode.`)
bootstrapAfter()
})
} catch (e) {
console.log(e)
}
})()

View File

@@ -1,20 +0,0 @@
import 'reflect-metadata'
import Koa from 'koa'
import { Container } from 'typedi'
import { routingConfigs } from './routing.options'
import { useMiddlewares } from './koa.middlewares'
import { useKoaServer, useContainer } from 'routing-controllers'
const createServer = async (): Promise<Koa> => {
const koa: Koa = new Koa()
useMiddlewares(koa)
useContainer(Container)
const app: Koa = useKoaServer<Koa>(koa, routingConfigs)
return app
}
export default createServer

View File

@@ -1,18 +0,0 @@
import { join } from 'path'
import { print } from './utils'
import dotenv from 'dotenv'
// "before" will trigger before the app lift.
export const bootstrapBefore = (): object => {
// solve ncc path link.
const result = dotenv.config({ path: join(__dirname, '../.env') })
if (result.error) {
print.danger('Environment variable not loaded: not found ".env" file.')
return {}
}
print.log('.env loaded.')
return result.parsed
}
// "after" will trigger after the "container" mounted..
export const bootstrapAfter = (): any => {}

View File

@@ -1,19 +0,0 @@
const { nodeExternalsPlugin } = require('esbuild-node-externals')
require('esbuild')
.build({
entryPoints: ['app.ts'],
bundle: true,
outfile: 'dist/index.js',
platform: 'node',
plugins: [
nodeExternalsPlugin({
dependencies: false,
}),
],
external: ['cors', 'kcors'],
})
.catch(err => {
console.log(err)
process.exit(1)
})

View File

@@ -1,23 +0,0 @@
import { PrismaClient } from '@prisma/client'
declare global {
namespace NodeJS {
interface Global {
prisma: PrismaClient
}
}
}
let prisma: PrismaClient
if (process.env.NODE_ENV === 'production') {
prisma = new PrismaClient()
} else {
if (!global.prisma) {
global.prisma = new PrismaClient()
}
prisma = global.prisma
}
export default prisma

View File

@@ -1,54 +0,0 @@
import { bootstrapBefore } from '../bootstrap'
import development, { EevRecord } from './development'
import staging from './staging'
import production from './production'
import { ENVS } from './envs'
const parsedEnvs = bootstrapBefore()
const getCurrentEnv = (): ENVS => {
const env = process.env?.ENV
if (typeof env === 'undefined') {
console.warn(`/n> ENV is not set, fallback to ${ENVS.DEVELOPMENT}.`)
}
const upperCaseEnv = `${env}`.toUpperCase()
if (upperCaseEnv === ENVS.PRODUCTION) return ENVS.PRODUCTION
if (upperCaseEnv === ENVS.STAGING) return ENVS.STAGING
return ENVS.DEVELOPMENT
}
const getCurrentConstants = (ident: ENVS): EevRecord => {
let constants = development
const source =
ident === ENVS.PRODUCTION
? production
: ident === ENVS.STAGING
? staging
: development
Object.keys(development).forEach(key => {
const sourceValue = source[key]
const processValue = process.env[key]
const parsedValue = parsedEnvs[key]
if (typeof sourceValue !== 'undefined') {
constants[key] = sourceValue
}
if (typeof processValue !== 'undefined') {
constants[key] = processValue
}
if (typeof parsedValue !== 'undefined') {
constants[key] = parsedValue
}
})
constants.ENV_LABEL = source.ENV_LABEL
return constants
}
export const CURRENT_ENV = getCurrentEnv()
export const isProd = () => CURRENT_ENV === ENVS.PRODUCTION
const CONSTANTS = getCurrentConstants(CURRENT_ENV)
export default CONSTANTS

View File

@@ -1,205 +0,0 @@
import { HttpParameterCodec } from '@angular/common/http';
import { Param } from './param';
export interface {{configurationParametersInterfaceName}} {
/**
* @deprecated Since 5.0. Use credentials instead
*/
apiKeys?: {[ key: string ]: string};
username?: string;
password?: string;
/**
* @deprecated Since 5.0. Use credentials instead
*/
accessToken?: string | (() => string);
basePath?: string;
withCredentials?: boolean;
/**
* Takes care of encoding query- and form-parameters.
*/
encoder?: HttpParameterCodec;
/**
* Override the default method for encoding path parameters in various
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values">styles</a>.
* <p>
* See {@link README.md} for more details
* </p>
*/
encodeParam?: (param: Param) => string;
/**
* The keys are the names in the securitySchemes section of the OpenAPI
* document. They should map to the value used for authentication
* minus any standard prefixes such as 'Basic' or 'Bearer'.
*/
credentials?: {[ key: string ]: string | (() => string | undefined)};
}
export class {{configurationClassName}} {
/**
* @deprecated Since 5.0. Use credentials instead
*/
apiKeys?: {[ key: string ]: string};
username?: string;
password?: string;
/**
* @deprecated Since 5.0. Use credentials instead
*/
accessToken?: string | (() => string);
basePath?: string;
withCredentials?: boolean;
/**
* Takes care of encoding query- and form-parameters.
*/
encoder?: HttpParameterCodec;
/**
* Encoding of various path parameter
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values">styles</a>.
* <p>
* See {@link README.md} for more details
* </p>
*/
encodeParam: (param: Param) => string;
/**
* The keys are the names in the securitySchemes section of the OpenAPI
* document. They should map to the value used for authentication
* minus any standard prefixes such as 'Basic' or 'Bearer'.
*/
credentials: {[ key: string ]: string | (() => string | undefined)};
constructor(configurationParameters: {{configurationParametersInterfaceName}} = {}) {
this.apiKeys = configurationParameters.apiKeys;
this.username = configurationParameters.username;
this.password = configurationParameters.password;
this.accessToken = configurationParameters.accessToken;
this.basePath = configurationParameters.basePath;
this.withCredentials = configurationParameters.withCredentials;
this.encoder = configurationParameters.encoder;
if (configurationParameters.encodeParam) {
this.encodeParam = configurationParameters.encodeParam;
}
else {
this.encodeParam = param => this.defaultEncodeParam(param);
}
if (configurationParameters.credentials) {
this.credentials = configurationParameters.credentials;
}
else {
this.credentials = {};
}
{{#authMethods}}
// init default {{name}} credential
if (!this.credentials['{{name}}']) {
{{#isApiKey}}
this.credentials['{{name}}'] = () => {
{{! Fallback behaviour may be removed for 5.0 release. See #5062 }}
if (this.apiKeys === null || this.apiKeys === undefined) {
return undefined;
} else {
return this.apiKeys['{{name}}'] || this.apiKeys['{{keyParamName}}'];
}
};
{{/isApiKey}}
{{#isBasic}}
{{#isBasicBasic}}
this.credentials['{{name}}'] = () => {
return (this.username || this.password)
? btoa(this.username + ':' + this.password)
: undefined;
};
{{/isBasicBasic}}
{{#isBasicBearer}}
this.credentials['{{name}}'] = () => {
return typeof this.accessToken === 'function'
? this.accessToken()
: this.accessToken;
};
{{/isBasicBearer}}
{{/isBasic}}
{{#isOAuth}}
this.credentials['{{name}}'] = () => {
return typeof this.accessToken === 'function'
? this.accessToken()
: this.accessToken;
};
{{/isOAuth}}
}
{{/authMethods}}
}
/**
* Select the correct content-type to use for a request.
* Uses {@link {{configurationClassName}}#isJsonMime} to determine the correct content-type.
* If no content type is found return the first found type if the contentTypes is not empty
* @param contentTypes - the array of content types that are available for selection
* @returns the selected content-type or <code>undefined</code> if no selection could be made.
*/
public selectHeaderContentType (contentTypes: string[]): string | undefined {
if (contentTypes.length === 0) {
return undefined;
}
const type = contentTypes.find((x: string) => this.isJsonMime(x));
if (type === undefined) {
return contentTypes[0];
}
return type;
}
/**
* Select the correct accept content-type to use for a request.
* Uses {@link {{configurationClassName}}#isJsonMime} to determine the correct accept content-type.
* If no content type is found return the first found type if the contentTypes is not empty
* @param accepts - the array of content types that are available for selection.
* @returns the selected content-type or <code>undefined</code> if no selection could be made.
*/
public selectHeaderAccept(accepts: string[]): string | undefined {
if (accepts.length === 0) {
return undefined;
}
const type = accepts.find((x: string) => this.isJsonMime(x));
if (type === undefined) {
return accepts[0];
}
return type;
}
/**
* Check if the given MIME is a JSON MIME.
* JSON MIME examples:
* application/json
* application/json; charset=UTF8
* APPLICATION/JSON
* application/vnd.company+json
* @param mime - MIME (Multipurpose Internet Mail Extensions)
* @return True if the given MIME is JSON, false otherwise.
*/
public isJsonMime(mime: string): boolean {
const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i');
return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json');
}
public lookupCredential(key: string): string | undefined {
const value = this.credentials[key];
return typeof value === 'function'
? value()
: value;
}
private defaultEncodeParam(param: Param): string {
// This implementation exists as fallback for missing configuration
// and for backwards compatibility to older typescript-angular generator versions.
// It only works for the 'simple' parameter style.
// Date-handling only works for the 'date-time' format.
// All other styles and Date-formats are probably handled incorrectly.
//
// But: if that's all you need (i.e.: the most common use-case): no need for customization!
const value = param.dataFormat === 'date-time' && param.value instanceof Date
? (param.value as Date).toISOString()
: param.value;
return encodeURIComponent(String(value));
}
}

View File

@@ -1,9 +0,0 @@
const development = {
ENV_LABEL: 'DEVELOPMENT',
PORT: 3001,
}
export default development
export type EevRecord = typeof development

View File

@@ -1,18 +0,0 @@
version: '3.3'
services:
restapi.postgres:
container_name: koa-ts
image: postgres:13
volumes:
- postgres:/var/lib/postgres
restart: always
ports:
- ${POSTGRES_PORT}:${POSTGRES_PORT}
env_file:
- ./.env
labels:
com.startupteam.description: "postgres container for koa-ts"
volumes:
postgres: {}

View File

@@ -1,20 +0,0 @@
import { HttpParameterCodec } from '@angular/common/http';
/**
* Custom HttpParameterCodec
* Workaround for https://github.com/angular/angular/issues/18261
*/
export class CustomHttpParameterCodec implements HttpParameterCodec {
encodeKey(k: string): string {
return encodeURIComponent(k);
}
encodeValue(v: string): string {
return encodeURIComponent(v);
}
decodeKey(k: string): string {
return decodeURIComponent(k);
}
decodeValue(v: string): string {
return decodeURIComponent(v);
}
}

View File

@@ -1,6 +0,0 @@
ENV=development
POSTGRES_USER=root
POSTGRES_PASSWORD=rootpassword
POSTGRES_DB=dev
POSTGRES_PORT=5432
DATABASE_URL='postgresql://root:rootpassword@localhost:5432/dev?schema=public'

View File

@@ -1,5 +0,0 @@
export enum ENVS {
DEVELOPMENT = 'DEVELOPMENT',
STAGING = 'STAGING',
PRODUCTION = 'PRODUCTION',
}

View File

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

View File

@@ -1,4 +0,0 @@
wwwroot/*.js
node_modules
typings
dist

View File

@@ -1,6 +0,0 @@
export * from './api/api';
export * from './model/models';
export * from './variables';
export * from './configuration';
export * from './api.module';
export * from './param';

View File

@@ -1 +0,0 @@
export * from './sessions.controller'

View File

@@ -1,12 +0,0 @@
import { InterceptorInterface, Action, Interceptor } from 'routing-controllers'
import { Service } from 'typedi'
@Interceptor()
@Service()
export class AutoAssignJSONInterceptor implements InterceptorInterface {
intercept(action: Action, content: any): any {
if (typeof content === 'object')
return JSON.stringify(Object.assign({ message: 'ok' }, content))
return JSON.stringify({ message: content })
}
}

View File

@@ -1,18 +0,0 @@
module.exports = {
verbose: true,
testEnvironment: 'node',
moduleFileExtensions: ['ts', 'js'],
testPathIgnorePatterns: ['/dist/'],
transform: {
'^.+\\.[t|j]s?$': ['ts-jest'],
},
transformIgnorePatterns: ['<rootDir>/node_modules/'],
testRegex: '.*\\.test\\.(j|t)s?$',
moduleNameMapper: {
'tests/(.*)$': '<rootDir>/tests/$1',
'configs/(.*)$': '<rootDir>/configs/$1',
'app/(.*)$': '<rootDir>/app/$1',
server: '<rootDir>/app.ts',
// app: '<rootDir>/app.ts',
},
}

View File

@@ -1,3 +0,0 @@
## Jobs
You can add scheduled tasks, email tasks, or any third-party work here.

View File

@@ -1,14 +0,0 @@
import Koa from 'koa'
import logger from 'koa-logger'
import bodyParser from 'koa-bodyparser'
import { isProd } from './constants'
export const useMiddlewares = <T extends Koa>(app: T): T => {
if (isProd()) {
app.use(logger())
}
app.use(bodyParser())
return app
}

View File

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

View File

@@ -1,16 +0,0 @@
{{>licenseInfo}}
{{#models}}
{{#model}}
{{#tsImports}}
import { {{classname}} } from '{{filename}}';
{{/tsImports}}
{{#description}}
/**
* {{{.}}}
*/
{{/description}}
{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{#isAlias}}{{>modelAlias}}{{/isAlias}}{{^isAlias}}{{#taggedUnions}}{{>modelTaggedUnion}}{{/taggedUnions}}{{^taggedUnions}}{{#oneOf}}{{#-first}}{{>modelOneOf}}{{/-first}}{{/oneOf}}{{^oneOf}}{{>modelGeneric}}{{/oneOf}}{{/taggedUnions}}{{/isAlias}}{{/isEnum}}
{{/model}}
{{/models}}

View File

@@ -1 +0,0 @@
export type {{classname}} = {{dataType}};

View File

@@ -1,20 +0,0 @@
{{#stringEnums}}
export enum {{classname}} {
{{#allowableValues}}
{{#enumVars}}
{{name}} = {{{value}}}{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
}
{{/stringEnums}}
{{^stringEnums}}
export type {{classname}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}};
export const {{classname}} = {
{{#allowableValues}}
{{#enumVars}}
{{name}}: {{{value}}} as {{classname}}{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
};
{{/stringEnums}}

View File

@@ -1,10 +0,0 @@
export interface {{classname}}{{#allParents}}{{#-first}} extends {{/-first}}{{{.}}}{{^-last}}, {{/-last}}{{/allParents}} { {{>modelGenericAdditionalProperties}}
{{#vars}}
{{#description}}
/**
* {{{.}}}
*/
{{/description}}
{{#isReadOnly}}readonly {{/isReadOnly}}{{{name}}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}} | null{{/isNullable}};
{{/vars}}
}{{>modelGenericEnums}}

View File

@@ -1,5 +0,0 @@
{{#additionalPropertiesType}}
[key: string]: {{{additionalPropertiesType}}}{{#hasVars}} | any{{/hasVars}};
{{/additionalPropertiesType}}

View File

@@ -1,30 +0,0 @@
{{#hasEnums}}
{{^stringEnums}}
export namespace {{classname}} {
{{/stringEnums}}
{{#vars}}
{{#isEnum}}
{{#stringEnums}}
export enum {{classname}}{{enumName}} {
{{#allowableValues}}
{{#enumVars}}
{{name}} = {{{value}}}{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
};
{{/stringEnums}}
{{^stringEnums}}
export type {{enumName}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}};
export const {{enumName}} = {
{{#allowableValues}}
{{#enumVars}}
{{name}}: {{{value}}} as {{enumName}}{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
};
{{/stringEnums}}
{{/isEnum}}
{{/vars}}
{{^stringEnums}}}{{/stringEnums}}
{{/hasEnums}}

View File

@@ -1,14 +0,0 @@
{{#hasImports}}
import {
{{#imports}}
{{{.}}},
{{/imports}}
} from './';
{{/hasImports}}
/**
* @type {{classname}}{{#description}}
* {{{.}}}{{/description}}
* @export
*/
export type {{classname}} = {{#oneOf}}{{{.}}}{{^-last}} | {{/-last}}{{/oneOf}};

View File

@@ -1,21 +0,0 @@
{{#discriminator}}
export type {{classname}} = {{#children}}{{^-first}} | {{/-first}}{{classname}}{{/children}};
{{/discriminator}}
{{^discriminator}}
{{#parent}}
export interface {{classname}} { {{>modelGenericAdditionalProperties}}
{{#allVars}}
{{#description}}
/**
* {{{.}}}
*/
{{/description}}
{{name}}{{^required}}?{{/required}}: {{#discriminatorValue}}'{{.}}'{{/discriminatorValue}}{{^discriminatorValue}}{{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{/discriminatorValue}}{{#isNullable}} | null{{/isNullable}};
{{/allVars}}
}
{{>modelGenericEnums}}
{{/parent}}
{{^parent}}
{{>modelGeneric}}
{{/parent}}
{{/discriminator}}

View File

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

View File

@@ -1,6 +0,0 @@
{
"$schema": "./node_modules/ng-packagr/ng-package.schema.json",
"lib": {
"entryFile": "index.ts"
}
}

View File

@@ -1,22 +0,0 @@
{
"verbose": false,
"debug": false,
"exec": "ts-node -r tsconfig-paths/register ./app.ts",
"ignore": [
"mochawesome-report",
"node_modules",
"./test",
"**/*.d.ts",
"*.test.ts",
"*.spec.ts",
"fixtures/*",
"test/**/*",
"docs/*"
],
"events": {
"restart": ""
},
"watch": ["./app", "./configs", "./app.ts"],
"ext": "ts",
"inspect": true
}

View File

@@ -1,58 +0,0 @@
{
"name": "{{{npmName}}}",
"version": "{{{npmVersion}}}",
"license": "Unlicense",
"main": "app.ts",
"scripts": {
"dev": "export NODE_ENV=development; ts-node-dev -r tsconfig-paths/register app.ts",
"dev:db": "docker compose -f docker-compose.yml up -d",
"prettier": "prettier --write '**/*.{js,ts}'",
"test": "jest --config .jest.config.js --no-cache --detectOpenHandles",
"prod:build": "node ./build.js",
"prod:start": "prisma generate && prisma migrate deploy && export NODE_ENV=production; node ./dist/index.js"
},
"repository": {
"type": "git",
"url": "https://{{gitHost}}/{{gitUserId}}/{{gitRepoId}}.git"
},
"keywords": [
"koa",
"openapi-server",
"openapi-generator"
],
"engines": {
"node": ">= 14.x"
},
"prettier": "@geist-ui/prettier-config",
"devDependencies": {
"@geist-ui/prettier-config": "^1.0.1",
"@types/jest": "^25.2.2",
"@types/koa": "^2.13.4",
"@types/koa-bodyparser": "^4.3.5",
"@types/node": "^17.0.8",
"esbuild": "^0.14.11",
"esbuild-node-externals": "^1.4.1",
"jest": "^26.6.3",
"prettier": "^2.5.1",
"prisma": "^4.6.1",
"supertest": "^4.0.2",
"ts-jest": "^26.5.3",
"ts-node-dev": "^2.0.0",
"tsconfig-paths": "^3.12.0",
"typescript": "^4.5.4"
},
"dependencies": {
"@prisma/client": "^4.6.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.13.2",
"dotenv": "^12.0.3",
"koa": "^2.13.4",
"koa-bodyparser": "^4.3.0",
"koa-logger": "^3.2.1",
"koa-multer": "^1.0.2",
"koa-router": "^10.1.1",
"reflect-metadata": "^0.1.13",
"routing-controllers": "^0.9.0",
"typedi": "^0.10.0"
}
}

View File

@@ -1,69 +0,0 @@
/**
* Standard parameter styles defined by OpenAPI spec
*/
export type StandardParamStyle =
| 'matrix'
| 'label'
| 'form'
| 'simple'
| 'spaceDelimited'
| 'pipeDelimited'
| 'deepObject'
;
/**
* The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user.
*/
export type ParamStyle = StandardParamStyle | string;
/**
* Standard parameter locations defined by OpenAPI spec
*/
export type ParamLocation = 'query' | 'header' | 'path' | 'cookie';
/**
* Standard types as defined in <a href="https://swagger.io/specification/#data-types">OpenAPI Specification: Data Types</a>
*/
export type StandardDataType =
| "integer"
| "number"
| "boolean"
| "string"
| "object"
| "array"
;
/**
* Standard {@link DataType}s plus your own types/classes.
*/
export type DataType = StandardDataType | string;
/**
* Standard formats as defined in <a href="https://swagger.io/specification/#data-types">OpenAPI Specification: Data Types</a>
*/
export type StandardDataFormat =
| "int32"
| "int64"
| "float"
| "double"
| "byte"
| "binary"
| "date"
| "date-time"
| "password"
;
export type DataFormat = StandardDataFormat | string;
/**
* The parameter to encode.
*/
export interface Param {
name: string;
value: unknown;
in: ParamLocation;
style: ParamStyle,
explode: boolean;
dataType: DataType;
dataFormat: DataFormat | undefined;
}

View File

@@ -1,7 +0,0 @@
import { EevRecord } from './development'
const production: Partial<EevRecord> = {
ENV_LABEL: 'PRODUCTION',
}
export default production

View File

@@ -1,18 +0,0 @@
import { KoaMiddlewareInterface, Middleware } from 'routing-controllers'
import { Service } from 'typedi'
@Middleware({ type: 'before' })
@Service()
export class HeaderMiddleware implements KoaMiddlewareInterface {
async use(context: any, next: (err?: any) => any): Promise<any> {
context.set('Access-Control-Allow-Methods', 'GET,HEAD,PUT,POST,DELETE,PATCH')
context.set(
'Access-Control-Allow-Origin',
context.request.header.origin || context.request.origin,
)
context.set('Access-Control-Allow-Headers', ['content-type'])
context.set('Access-Control-Allow-Credentials', 'true')
context.set('Content-Type', 'application/json; charset=utf-8')
return next()
}
}

View File

@@ -1,21 +0,0 @@
import { RoutingControllersOptions } from 'routing-controllers'
import * as controllers from 'app/controllers'
import * as middlewares from './routing.middlewares'
import * as interceptors from './interceptors'
import { dictToArray } from './utils'
export const routingConfigs: RoutingControllersOptions = {
controllers: dictToArray(controllers),
middlewares: dictToArray(middlewares),
interceptors: dictToArray(interceptors),
// router prefix
// e.g. api => http://hostname:port/{routePrefix}/{controller.method}
routePrefix: '/apis',
// auto validate entity item
// learn more: https://github.com/typestack/class-validator
validation: true,
}

View File

@@ -1,14 +0,0 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Session {
id Int @id @default(autoincrement())
name String
createdAt DateTime @default(now())
}

View File

@@ -1,19 +0,0 @@
import server from 'server'
import request from 'supertest'
describe('routers: session', () => {
let app
beforeAll(async () => {
app = await server
})
it('should be return 200 status code', async () => {
const res = await request(app).get('/apis/sessions')
expect(res.status).toEqual(200)
})
afterAll(async done => {
app.close()
done()
})
})

View File

@@ -1,31 +0,0 @@
import {
BadRequestError,
Post,
JsonController,
BodyParam,
Get,
} from 'routing-controllers'
import { SessionsService } from '../services'
import { Prisma } from '@prisma/client'
import { Service } from 'typedi'
@JsonController()
@Service()
export class SessionsController {
constructor(private sessionsService: SessionsService) {}
@Get('/sessions')
async query() {
return []
}
@Post('/sessions')
async create(
@BodyParam('username') name: string,
): Promise<Prisma.SessionGetPayload<any>> {
if (!name) {
throw new BadRequestError('username is required')
}
return await this.sessionsService.create({ name })
}
}

View File

@@ -1 +0,0 @@
export * from './sessions.service'

View File

@@ -1,21 +0,0 @@
import { Service } from 'typedi'
import prisma from 'app/helpers/client'
import { Prisma } from '@prisma/client'
@Service()
export class SessionsService {
/**
* Type 'Prisma.SessionCreateInput' is automatically generated.
* Whenever you modify file 'prisma/schema.prisma' and then run command:
* prisma generate
* prisma migrate dev
* The types is automatically updated.
*
* About CRUD: https://www.prisma.io/docs/concepts/components/prisma-client/crud
*/
async create(session: Prisma.SessionCreateInput) {
return prisma.session.create({
data: session,
})
}
}

View File

@@ -1,7 +0,0 @@
import { EevRecord } from './development'
const staging: Partial<EevRecord> = {
ENV_LABEL: 'STAGING',
}
export default staging

View File

@@ -1,39 +0,0 @@
{
"compilerOptions": {
"allowJs": true,
"moduleResolution": "Node",
"module": "commonjs",
"outDir": "./dist",
"lib": ["ESNext"],
"removeComments": true,
"skipLibCheck": true,
"noImplicitAny": false,
"esModuleInterop": true,
"preserveConstEnums": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"typeRoots": [
"node_modules/@types",
"typings"
],
"baseUrl": ".",
"paths": {
"configs/*": ["./configs/*"],
"app": ["app"]
},
},
"compileOnSave": false,
"include": [
"app/**/*",
"configs/**/*",
"**/*.ts",
"**/*.tsx"
],
"files": [
"app.ts",
],
"exclude": [
"node_modules",
"dist"
]
}

View File

@@ -1,8 +0,0 @@
export const dictToArray = (dict: object): Array<any> =>
Object.keys(dict).map(name => dict[name])
export const print = {
log: (text: string) => console.log('\x1b[37m%s \x1b[2m%s\x1b[0m', '>', text),
danger: (text: string) => console.log('\x1b[31m%s \x1b[31m%s\x1b[0m', '>', text),
tip: (text: string) => console.log('\x1b[36m%s \x1b[36m%s\x1b[0m', '>', text),
}

View File

@@ -1,9 +0,0 @@
import { InjectionToken } from '@angular/core';
export const BASE_PATH = new InjectionToken<string>('basePath');
export const COLLECTION_FORMATS = {
'csv': ',',
'tsv': ' ',
'ssv': ' ',
'pipes': '|'
}

View File

@@ -103,7 +103,7 @@ export class {{classname}} {
{{/queryParams}}
{{/hasQueryParams}}
let headers = {...this.defaultHeaders};
let headers = this.defaultHeaders;
{{#headerParams}}
{{#isArray}}
if ({{paramName}}) {

View File

@@ -1,3 +1,10 @@
{{#platforms}}
{{#node}}
// typings for btoa are incorrect
//@ts-ignore
import {{^supportsES6}}* as{{/supportsES6}} btoa from "btoa";
{{/node}}
{{/platforms}}
import { RequestContext } from "../http/http{{extensionForDeno}}";
{{#useInversify}}
import { injectable, inject, named } from "inversify";
@@ -85,8 +92,8 @@ export class {{#lambda.pascalcase}}{{name}}{{/lambda.pascalcase}}Authentication
context.{{#isKeyInHeader}}setHeaderParam{{/isKeyInHeader}}{{#isKeyInQuery}}setQueryParam{{/isKeyInQuery}}{{#isKeyInCookie}}addCookie{{/isKeyInCookie}}("{{keyParamName}}", this.apiKey);
{{/isApiKey}}
{{#isBasicBasic}}
let comb = Buffer.from(this.username + ":" + this.password, 'binary').toString('base64');
context.setHeaderParam("Authorization", "Basic " + comb);
let comb = this.username + ":" + this.password;
context.setHeaderParam("Authorization", "Basic " + btoa(comb));
{{/isBasicBasic}}
{{#isBasicBearer}}
context.setHeaderParam("Authorization", "Bearer " + await this.tokenProvider.getToken());

View File

@@ -52,6 +52,7 @@
{{#node}}
"@types/node": "*",
"form-data": "^2.5.0",
"btoa": "^1.2.1",
{{/node}}
{{/platforms}}
{{#useRxJS}}

View File

@@ -160,7 +160,7 @@ public class GoClientCodegenTest {
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);
TestUtils.assertFileContains(Paths.get(output + "/model_example.go"), "Child NullableChild");
TestUtils.assertFileContains(Paths.get(output + "/model_example.go"), "Child NullableExampleChild");
}
@Test

View File

@@ -102,7 +102,6 @@ public class Swift5OptionsProvider implements OptionsProvider {
.put(Swift5ClientCodegen.USE_JSON_ENCODABLE, USE_JSON_ENCODABLE_VALUE)
.put(Swift5ClientCodegen.MAP_FILE_BINARY_TO_DATA, "false")
.put(Swift5ClientCodegen.USE_CUSTOM_DATE_WITHOUT_TIME, "false")
.put(Swift5ClientCodegen.VALIDATABLE, "true")
.put(Swift5ClientCodegen.USE_CLASSES, "false")
.put(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE, ENUM_UNKNOWN_DEFAULT_CASE_VALUE)
.build();

View File

@@ -470,14 +470,4 @@ public class TypeScriptFetchModelTest {
final Map<String, Schema> schemaBefore = openAPI.getComponents().getSchemas();
Assert.assertEquals(schemaBefore.keySet(), Sets.newHashSet("club", "owner"));
}
@Test(description = "Don't generate new schemas for nullable references")
public void testNestedNullableSchemas() {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/allOf-nullable.yaml");
final DefaultCodegen codegen = new TypeScriptFetchClientCodegen();
codegen.processOpts();
codegen.setOpenAPI(openAPI);
final Map<String, Schema> schemaBefore = openAPI.getComponents().getSchemas();
Assert.assertEquals(schemaBefore.keySet(), Sets.newHashSet("club", "owner"));
}
}

View File

@@ -1,40 +0,0 @@
openapi: 3.0.1
info:
version: 1.0.0
title: Example
license:
name: MIT
servers:
- url: http://api.example.xyz/v1
paths:
/person/display/{personId}:
get:
parameters:
- name: personId
in: path
required: true
description: The id of the person to retrieve
schema:
type: string
operationId: list
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/club"
components:
schemas:
club:
properties:
owner:
allOf:
- $ref: '#/components/schemas/owner'
nullable: true
owner:
properties:
name:
type: string
maxLength: 255

View File

@@ -1594,14 +1594,6 @@ paths:
responses:
'200':
description: OK
'202':
description: header only
headers:
X-Rate-Limit:
description: calls per hour allowed by the user
schema:
type: string
format: number
default:
description: Unexpected error
/fake/queryParamWithJsonContentType:

View File

@@ -1,738 +0,0 @@
openapi: 3.0.0
servers:
- url: 'http://petstore.swagger.io/v2'
info:
description: >-
This is a sample server Petstore server. For this sample, you can use the api key
`special-key` to test the authorization filters.
version: 1.0.0
title: OpenAPI Petstore
license:
name: Apache-2.0
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: pet
description: Everything about your Pets
- name: store
description: Access to Petstore orders
- name: user
description: Operations about user
paths:
/pet:
post:
tags:
- pet
summary: Add a new pet to the store
description: ''
operationId: addPet
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
$ref: '#/components/requestBodies/Pet'
put:
tags:
- pet
summary: Update an existing pet
description: ''
operationId: updatePet
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid ID supplied
'404':
description: Pet not found
'405':
description: Validation exception
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
$ref: '#/components/requestBodies/Pet'
/pet/findByStatus:
get:
tags:
- pet
summary: Finds Pets by status
description: Multiple status values can be provided with comma separated strings
operationId: findPetsByStatus
parameters:
- name: status
in: query
description: Status values that need to be considered for filter
required: true
style: form
explode: false
deprecated: true
schema:
type: array
items:
type: string
enum:
- available
- pending
- sold
default: available
responses:
'200':
description: successful operation
content:
application/xml:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid status value
security:
- petstore_auth:
- 'read:pets'
/pet/findByTags:
get:
tags:
- pet
summary: Finds Pets by tags
description: >-
Multiple tags can be provided with comma separated strings. Use tag1,
tag2, tag3 for testing.
operationId: findPetsByTags
parameters:
- name: tags
in: query
description: Tags to filter by
required: true
style: form
explode: false
schema:
type: array
items:
type: string
responses:
'200':
description: successful operation
content:
application/xml:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid tag value
security:
- petstore_auth:
- 'read:pets'
deprecated: true
'/pet/{petId}':
get:
tags:
- pet
summary: Find pet by ID
description: Returns a single pet
operationId: getPetById
parameters:
- name: petId
in: path
description: ID of pet to return
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid ID supplied
'404':
description: Pet not found
security:
- api_key: []
post:
tags:
- pet
summary: Updates a pet in the store with form data
description: ''
operationId: updatePetWithForm
parameters:
- name: petId
in: path
description: ID of pet that needs to be updated
required: true
schema:
type: integer
format: int64
responses:
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
name:
description: Updated name of the pet
type: string
status:
description: Updated status of the pet
type: string
delete:
tags:
- pet
summary: Deletes a pet
description: ''
operationId: deletePet
parameters:
- name: api_key
in: header
required: false
schema:
type: string
- name: petId
in: path
description: Pet id to delete
required: true
schema:
type: integer
format: int64
responses:
'400':
description: Invalid pet value
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
'/pet/{petId}/uploadImage':
post:
tags:
- pet
summary: uploads an image
description: ''
operationId: uploadFile
parameters:
- name: petId
in: path
description: ID of pet to update
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
additionalMetadata:
description: Additional data to pass to server
type: string
file:
description: file to upload
type: string
format: binary
/store/inventory:
get:
tags:
- store
summary: Returns pet inventories by status
description: Returns a map of status codes to quantities
operationId: getInventory
responses:
'200':
description: successful operation
content:
application/json:
schema:
type: object
additionalProperties:
type: integer
format: int32
security:
- api_key: []
/store/order:
post:
tags:
- store
summary: Place an order for a pet
description: ''
operationId: placeOrder
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Order'
application/json:
schema:
$ref: '#/components/schemas/Order'
'400':
description: Invalid Order
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
description: order placed for purchasing the pet
required: true
'/store/order/{orderId}':
get:
tags:
- store
summary: Find purchase order by ID
description: >-
For valid response try integer IDs with value <= 5 or > 10. Other values
will generate exceptions
operationId: getOrderById
parameters:
- name: orderId
in: path
description: ID of pet that needs to be fetched
required: true
schema:
type: integer
format: int64
minimum: 1
maximum: 5
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Order'
application/json:
schema:
$ref: '#/components/schemas/Order'
'400':
description: Invalid ID supplied
'404':
description: Order not found
delete:
tags:
- store
summary: Delete purchase order by ID
description: >-
For valid response try integer IDs with value < 1000. Anything above
1000 or nonintegers will generate API errors
operationId: deleteOrder
parameters:
- name: orderId
in: path
description: ID of the order that needs to be deleted
required: true
schema:
type: string
responses:
'400':
description: Invalid ID supplied
'404':
description: Order not found
/user:
post:
tags:
- user
summary: Create user
description: This can only be done by the logged in user.
operationId: createUser
responses:
default:
description: successful operation
security:
- api_key: []
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
description: Created user object
required: true
/user/createWithArray:
post:
tags:
- user
summary: Creates list of users with given input array
description: ''
operationId: createUsersWithArrayInput
responses:
default:
description: successful operation
security:
- api_key: []
requestBody:
$ref: '#/components/requestBodies/UserArray'
/user/createWithList:
post:
tags:
- user
summary: Creates list of users with given input array
description: ''
operationId: createUsersWithListInput
responses:
default:
description: successful operation
security:
- api_key: []
requestBody:
$ref: '#/components/requestBodies/UserArray'
/user/login:
get:
tags:
- user
summary: Logs user into the system
description: ''
operationId: loginUser
parameters:
- name: username
in: query
description: The user name for login
required: true
schema:
type: string
pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$'
- name: password
in: query
description: The password for login in clear text
required: true
schema:
type: string
responses:
'200':
description: successful operation
headers:
Set-Cookie:
description: >-
Cookie authentication key for use with the `api_key`
apiKey authentication.
schema:
type: string
example: AUTH_KEY=abcde12345; Path=/; HttpOnly
X-Rate-Limit:
description: calls per hour allowed by the user
schema:
type: integer
format: int32
X-Expires-After:
description: date in UTC when token expires
schema:
type: string
format: date-time
content:
application/xml:
schema:
type: string
application/json:
schema:
type: string
'400':
description: Invalid username/password supplied
/user/logout:
get:
tags:
- user
summary: Logs out current logged in user session
description: ''
operationId: logoutUser
responses:
default:
description: successful operation
security:
- api_key: []
'/user/{username}':
get:
tags:
- user
summary: Get user by user name
description: ''
operationId: getUserByName
parameters:
- name: username
in: path
description: The name that needs to be fetched. Use user1 for testing.
required: true
schema:
type: string
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/User'
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Invalid username supplied
'404':
description: User not found
put:
tags:
- user
summary: Updated user
description: This can only be done by the logged in user.
operationId: updateUser
parameters:
- name: username
in: path
description: name that need to be deleted
required: true
schema:
type: string
responses:
'400':
description: Invalid user supplied
'404':
description: User not found
security:
- api_key: []
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
description: Updated user object
required: true
delete:
tags:
- user
summary: Delete user
description: This can only be done by the logged in user.
operationId: deleteUser
parameters:
- name: username
in: path
description: The name that needs to be deleted
required: true
schema:
type: string
responses:
'400':
description: Invalid username supplied
'404':
description: User not found
security:
- api_key: []
externalDocs:
description: Find out more about Swagger
url: 'http://swagger.io'
components:
requestBodies:
UserArray:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
description: List of user object
required: true
Pet:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
description: Pet object that needs to be added to the store
required: true
securitySchemes:
petstore_auth:
type: oauth2
flows:
implicit:
authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
scopes:
'write:pets': modify pets in your account
'read:pets': read your pets
api_key:
type: apiKey
name: api_key
in: header
schemas:
Order:
title: Pet Order
description: An order for a pets from the pet store
type: object
properties:
id:
type: integer
format: int64
petId:
type: integer
format: int64
quantity:
type: integer
format: int32
shipDate:
type: string
format: date-time
status:
type: string
description: Order Status
enum:
- placed
- approved
- delivered
complete:
type: boolean
default: false
xml:
name: Order
Category:
title: Pet category
description: A category for a pet
type: object
properties:
id:
type: integer
format: int64
name:
type: string
pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$'
xml:
name: Category
User:
title: a User
description: A User who is purchasing from the pet store
type: object
properties:
id:
type: integer
format: int64
username:
type: string
firstName:
type: string
lastName:
type: string
email:
type: string
password:
type: string
phone:
type: string
userStatus:
type: integer
format: int32
description: User Status
xml:
name: User
Tag:
title: Pet Tag
description: A tag for a pet
type: object
properties:
id:
type: integer
format: int64
name:
type: string
xml:
name: Tag
Pet:
title: a Pet
description: A pet for sale in the pet store
type: object
required:
- name
- photoUrls
properties:
id:
type: integer
format: int64
category:
$ref: '#/components/schemas/Category'
name:
type: string
example: doggie
photoUrls:
type: array
xml:
name: photoUrl
wrapped: true
items:
type: string
tags:
type: array
xml:
name: tag
wrapped: true
items:
$ref: '#/components/schemas/Tag'
status:
type: string
description: pet status in the store
deprecated: true
enum:
- available
- pending
- sold
xml:
name: Pet
ApiResponse:
title: An uploaded response
description: Describes the result of uploading an image resource
type: object
properties:
code:
type: integer
format: int32
type:
type: string
message:
type: string

View File

@@ -1,26 +0,0 @@
openapi: 3.0.1
info:
title: fruity
version: 0.0.1
paths:
/:
get:
responses:
'200':
description: desc
content:
application/json:
schema:
$ref: '#/components/schemas/banana'
components:
schemas:
banana:
title: banana
properties:
count:
type: integer
minimum: 10
exclusiveMinimum: true
maximum: 100
exclusiveMaximum: true
multipleOf: 5

View File

@@ -1193,6 +1193,11 @@
<module>samples/server/petstore/python-aiohttp-srclayout</module>
<module>samples/server/petstore/python-fastapi</module>
<module>samples/server/petstore/python-flask</module>
<module>samples/server/petstore/java-camel</module>
<module>samples/server/petstore/java-vertx-web</module>
<module>samples/server/petstore/java-inflector</module>
<module>samples/server/petstore/java-pkmst</module>
<module>samples/server/petstore/java-undertow</module>
</modules>
</profile>
<profile>

View File

@@ -68,7 +68,7 @@ public interface QueryApi extends ApiClient.Api {
@Headers({
"Accept: text/plain",
})
String testQueryIntegerBooleanString(@QueryMap(encoded=true) TestQueryIntegerBooleanStringQueryParams queryParams);
String testQueryIntegerBooleanString(@QueryMap(encoded=true) Map<String, Object> queryParams);
/**
* Test query parameter(s)
@@ -88,7 +88,7 @@ public interface QueryApi extends ApiClient.Api {
@Headers({
"Accept: text/plain",
})
ApiResponse<String> testQueryIntegerBooleanStringWithHttpInfo(@QueryMap(encoded=true) TestQueryIntegerBooleanStringQueryParams queryParams);
ApiResponse<String> testQueryIntegerBooleanStringWithHttpInfo(@QueryMap(encoded=true) Map<String, Object> queryParams);
/**
@@ -155,7 +155,7 @@ public interface QueryApi extends ApiClient.Api {
@Headers({
"Accept: text/plain",
})
String testQueryStyleFormExplodeTrueArrayString(@QueryMap(encoded=true) TestQueryStyleFormExplodeTrueArrayStringQueryParams queryParams);
String testQueryStyleFormExplodeTrueArrayString(@QueryMap(encoded=true) Map<String, Object> queryParams);
/**
* Test query parameter(s)
@@ -173,7 +173,7 @@ public interface QueryApi extends ApiClient.Api {
@Headers({
"Accept: text/plain",
})
ApiResponse<String> testQueryStyleFormExplodeTrueArrayStringWithHttpInfo(@QueryMap(encoded=true) TestQueryStyleFormExplodeTrueArrayStringQueryParams queryParams);
ApiResponse<String> testQueryStyleFormExplodeTrueArrayStringWithHttpInfo(@QueryMap(encoded=true) Map<String, Object> queryParams);
/**
@@ -232,7 +232,7 @@ public interface QueryApi extends ApiClient.Api {
@Headers({
"Accept: text/plain",
})
String testQueryStyleFormExplodeTrueObject(@QueryMap(encoded=true) TestQueryStyleFormExplodeTrueObjectQueryParams queryParams);
String testQueryStyleFormExplodeTrueObject(@QueryMap(encoded=true) Map<String, Object> queryParams);
/**
* Test query parameter(s)
@@ -250,7 +250,7 @@ public interface QueryApi extends ApiClient.Api {
@Headers({
"Accept: text/plain",
})
ApiResponse<String> testQueryStyleFormExplodeTrueObjectWithHttpInfo(@QueryMap(encoded=true) TestQueryStyleFormExplodeTrueObjectQueryParams queryParams);
ApiResponse<String> testQueryStyleFormExplodeTrueObjectWithHttpInfo(@QueryMap(encoded=true) Map<String, Object> queryParams);
/**

View File

@@ -0,0 +1,30 @@
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
#
# This file is auto-generated by OpenAPI Generator (https://openapi-generator.tech)
name: Java CI with Maven
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
build:
name: Build Echo Server API
runs-on: ubuntu-latest
strategy:
matrix:
java: [ '8' ]
steps:
- uses: actions/checkout@v2
- name: Set up JDK
uses: actions/setup-java@v2
with:
java-version: ${{ matrix.java }}
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn -B package --no-transfer-progress --file pom.xml

View File

@@ -0,0 +1,21 @@
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# exclude jar for gradle wrapper
!gradle/wrapper/*.jar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# build files
**/target
target
.gradle
build

View File

@@ -0,0 +1,39 @@
.github/workflows/maven.yml
.gitignore
.travis.yml
README.md
api/openapi.yaml
build.gradle
build.sbt
docs/BodyApi.md
docs/Category.md
docs/PathApi.md
docs/Pet.md
docs/QueryApi.md
docs/Tag.md
docs/TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter.md
git_push.sh
gradle.properties
gradle/wrapper/gradle-wrapper.jar
gradle/wrapper/gradle-wrapper.properties
gradlew
gradlew.bat
pom.xml
settings.gradle
src/main/AndroidManifest.xml
src/main/java/org/openapitools/client/ApiClient.java
src/main/java/org/openapitools/client/JavaTimeFormatter.java
src/main/java/org/openapitools/client/RFC3339DateFormat.java
src/main/java/org/openapitools/client/ServerConfiguration.java
src/main/java/org/openapitools/client/ServerVariable.java
src/main/java/org/openapitools/client/api/BodyApi.java
src/main/java/org/openapitools/client/api/PathApi.java
src/main/java/org/openapitools/client/api/QueryApi.java
src/main/java/org/openapitools/client/auth/ApiKeyAuth.java
src/main/java/org/openapitools/client/auth/Authentication.java
src/main/java/org/openapitools/client/auth/HttpBasicAuth.java
src/main/java/org/openapitools/client/auth/HttpBearerAuth.java
src/main/java/org/openapitools/client/model/Category.java
src/main/java/org/openapitools/client/model/Pet.java
src/main/java/org/openapitools/client/model/Tag.java
src/main/java/org/openapitools/client/model/TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter.java

View File

@@ -0,0 +1,22 @@
#
# Generated by OpenAPI Generator: https://openapi-generator.tech
#
# Ref: https://docs.travis-ci.com/user/languages/java/
#
language: java
jdk:
- openjdk12
- openjdk11
- openjdk10
- openjdk9
- openjdk8
before_install:
# ensure gradlew has proper permission
- chmod a+x ./gradlew
script:
# test using maven
#- mvn test
# test using gradle
- gradle test
# test using sbt
# - sbt test

View File

@@ -0,0 +1,143 @@
# echo-api-resttemplate
Echo Server API
- API version: 0.1.0
Echo Server API
*Automatically generated by the [OpenAPI Generator](https://openapi-generator.tech)*
## Requirements
Building the API client library requires:
1. Java 1.8+
2. Maven/Gradle
## Installation
To install the API client library to your local Maven repository, simply execute:
```shell
mvn clean install
```
To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
```shell
mvn clean deploy
```
Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information.
### Maven users
Add this dependency to your project's POM:
```xml
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>echo-api-resttemplate</artifactId>
<version>0.1.0</version>
<scope>compile</scope>
</dependency>
```
### Gradle users
Add this dependency to your project's build file:
```groovy
repositories {
mavenCentral() // Needed if the 'echo-api-resttemplate' jar has been published to maven central.
mavenLocal() // Needed if the 'echo-api-resttemplate' jar has been published to the local maven repo.
}
dependencies {
implementation "org.openapitools:echo-api-resttemplate:0.1.0"
}
```
### Others
At first generate the JAR by executing:
```shell
mvn clean package
```
Then manually install the following JARs:
- `target/echo-api-resttemplate-0.1.0.jar`
- `target/lib/*.jar`
## Getting Started
Please follow the [installation](#installation) instruction and execute the following Java code:
```java
import org.openapitools.client.*;
import org.openapitools.client.auth.*;
import org.openapitools.client.model.*;
import org.openapitools.client.api.BodyApi;
public class BodyApiExample {
public static void main(String[] args) {
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("http://localhost:3000");
BodyApi apiInstance = new BodyApi(defaultClient);
Pet pet = new Pet(); // Pet | Pet object that needs to be added to the store
try {
Pet result = apiInstance.testEchoBodyPet(pet);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling BodyApi#testEchoBodyPet");
System.err.println("Status code: " + e.getCode());
System.err.println("Reason: " + e.getResponseBody());
System.err.println("Response headers: " + e.getResponseHeaders());
e.printStackTrace();
}
}
}
```
## Documentation for API Endpoints
All URIs are relative to *http://localhost:3000*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
*BodyApi* | [**testEchoBodyPet**](docs/BodyApi.md#testEchoBodyPet) | **POST** /echo/body/Pet | Test body parameter(s)
*PathApi* | [**testsPathStringPathStringIntegerPathInteger**](docs/PathApi.md#testsPathStringPathStringIntegerPathInteger) | **GET** /path/string/{path_string}/integer/{path_integer} | Test path parameter(s)
*QueryApi* | [**testQueryIntegerBooleanString**](docs/QueryApi.md#testQueryIntegerBooleanString) | **GET** /query/integer/boolean/string | Test query parameter(s)
*QueryApi* | [**testQueryStyleFormExplodeTrueArrayString**](docs/QueryApi.md#testQueryStyleFormExplodeTrueArrayString) | **GET** /query/style_form/explode_true/array_string | Test query parameter(s)
*QueryApi* | [**testQueryStyleFormExplodeTrueObject**](docs/QueryApi.md#testQueryStyleFormExplodeTrueObject) | **GET** /query/style_form/explode_true/object | Test query parameter(s)
## Documentation for Models
- [Category](docs/Category.md)
- [Pet](docs/Pet.md)
- [Tag](docs/Tag.md)
- [TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter](docs/TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter.md)
## Documentation for Authorization
All endpoints do not require authorization.
Authentication schemes defined for the API:
## Recommendation
It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues.
## Author
team@openapitools.org

View File

@@ -0,0 +1,242 @@
openapi: 3.0.3
info:
contact:
email: team@openapitools.org
description: Echo Server API
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
title: Echo Server API
version: 0.1.0
servers:
- url: http://localhost:3000/
paths:
/path/string/{path_string}/integer/{path_integer}:
get:
description: Test path parameter(s)
operationId: "tests/path/string/{path_string}/integer/{path_integer}"
parameters:
- explode: false
in: path
name: path_string
required: true
schema:
type: string
style: simple
- explode: false
in: path
name: path_integer
required: true
schema:
type: integer
style: simple
responses:
"200":
content:
text/plain:
schema:
type: string
description: Successful operation
summary: Test path parameter(s)
tags:
- path
x-accepts: text/plain
/query/integer/boolean/string:
get:
description: Test query parameter(s)
operationId: test/query/integer/boolean/string
parameters:
- explode: true
in: query
name: integer_query
required: false
schema:
type: integer
style: form
- explode: true
in: query
name: boolean_query
required: false
schema:
type: boolean
style: form
- explode: true
in: query
name: string_query
required: false
schema:
type: string
style: form
responses:
"200":
content:
text/plain:
schema:
type: string
description: Successful operation
summary: Test query parameter(s)
tags:
- query
x-accepts: text/plain
/query/style_form/explode_true/array_string:
get:
description: Test query parameter(s)
operationId: test/query/style_form/explode_true/array_string
parameters:
- explode: true
in: query
name: query_object
required: false
schema:
$ref: '#/components/schemas/test_query_style_form_explode_true_array_string_query_object_parameter'
style: form
responses:
"200":
content:
text/plain:
schema:
type: string
description: Successful operation
summary: Test query parameter(s)
tags:
- query
x-accepts: text/plain
/query/style_form/explode_true/object:
get:
description: Test query parameter(s)
operationId: test/query/style_form/explode_true/object
parameters:
- explode: true
in: query
name: query_object
required: false
schema:
$ref: '#/components/schemas/Pet'
style: form
responses:
"200":
content:
text/plain:
schema:
type: string
description: Successful operation
summary: Test query parameter(s)
tags:
- query
x-accepts: text/plain
/echo/body/Pet:
post:
description: Test body parameter(s)
operationId: test/echo/body/Pet
requestBody:
$ref: '#/components/requestBodies/Pet'
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
description: Successful operation
summary: Test body parameter(s)
tags:
- body
x-content-type: application/json
x-accepts: application/json
components:
requestBodies:
Pet:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
description: Pet object that needs to be added to the store
schemas:
Category:
example:
name: Dogs
id: 1
properties:
id:
example: 1
format: int64
type: integer
name:
example: Dogs
type: string
type: object
xml:
name: category
Tag:
example:
name: name
id: 0
properties:
id:
format: int64
type: integer
name:
type: string
type: object
xml:
name: tag
Pet:
example:
photoUrls:
- photoUrls
- photoUrls
name: doggie
id: 10
category:
name: Dogs
id: 1
tags:
- name: name
id: 0
- name: name
id: 0
status: available
properties:
id:
example: 10
format: int64
type: integer
name:
example: doggie
type: string
category:
$ref: '#/components/schemas/Category'
photoUrls:
items:
type: string
xml:
name: photoUrl
type: array
xml:
wrapped: true
tags:
items:
$ref: '#/components/schemas/Tag'
type: array
xml:
wrapped: true
status:
description: pet status in the store
enum:
- available
- pending
- sold
type: string
required:
- name
- photoUrls
type: object
xml:
name: pet
test_query_style_form_explode_true_array_string_query_object_parameter:
properties:
values:
items:
type: string
type: array
type: object

View File

@@ -0,0 +1,123 @@
apply plugin: 'idea'
apply plugin: 'eclipse'
group = 'org.openapitools'
version = '0.1.0'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.+'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
}
}
repositories {
mavenCentral()
}
if(hasProperty('target') && target == 'android') {
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
android {
compileSdkVersion 23
buildToolsVersion '23.0.2'
defaultConfig {
minSdkVersion 14
targetSdkVersion 22
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// Rename the aar correctly
libraryVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.aar')) {
def fileName = "${project.name}-${variant.baseName}-${version}.aar"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
dependencies {
provided "jakarta.annotation:jakarta.annotation-api:$jakarta_annotation_version"
}
}
afterEvaluate {
android.libraryVariants.all { variant ->
def task = project.tasks.create "jar${variant.name.capitalize()}", Jar
task.description = "Create jar artifact for ${variant.name}"
task.dependsOn variant.javaCompile
task.from variant.javaCompile.destinationDir
task.destinationDir = project.file("${project.buildDir}/outputs/jar")
task.archiveName = "${project.name}-${variant.baseName}-${version}.jar"
artifacts.add('archives', task);
}
}
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
artifacts {
archives sourcesJar
}
} else {
apply plugin: 'java'
apply plugin: 'maven-publish'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
publishing {
publications {
maven(MavenPublication) {
artifactId = 'echo-api-resttemplate'
from components.java
}
}
}
task execute(type:JavaExec) {
main = System.getProperty('mainClass')
classpath = sourceSets.main.runtimeClasspath
}
}
ext {
swagger_annotations_version = "1.6.9"
jackson_version = "2.14.1"
jackson_databind_version = "2.14.1"
jackson_databind_nullable_version = "0.2.4"
jakarta_annotation_version = "1.3.5"
spring_web_version = "5.3.24"
jodatime_version = "2.9.9"
junit_version = "4.13.2"
}
dependencies {
implementation "io.swagger:swagger-annotations:$swagger_annotations_version"
implementation "com.google.code.findbugs:jsr305:3.0.2"
implementation "org.springframework:spring-web:$spring_web_version"
implementation "org.springframework:spring-context:$spring_web_version"
implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version"
implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_databind_version"
implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version"
implementation "org.openapitools:jackson-databind-nullable:$jackson_databind_nullable_version"
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version"
implementation "jakarta.annotation:jakarta.annotation-api:$jakarta_annotation_version"
testImplementation "junit:junit:$junit_version"
}

View File

@@ -0,0 +1 @@
# TODO

View File

@@ -0,0 +1,75 @@
# BodyApi
All URIs are relative to *http://localhost:3000*
| Method | HTTP request | Description |
|------------- | ------------- | -------------|
| [**testEchoBodyPet**](BodyApi.md#testEchoBodyPet) | **POST** /echo/body/Pet | Test body parameter(s) |
## testEchoBodyPet
> Pet testEchoBodyPet(pet)
Test body parameter(s)
Test body parameter(s)
### Example
```java
// Import classes:
import org.openapitools.client.ApiClient;
import org.openapitools.client.ApiException;
import org.openapitools.client.Configuration;
import org.openapitools.client.models.*;
import org.openapitools.client.api.BodyApi;
public class Example {
public static void main(String[] args) {
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("http://localhost:3000");
BodyApi apiInstance = new BodyApi(defaultClient);
Pet pet = new Pet(); // Pet | Pet object that needs to be added to the store
try {
Pet result = apiInstance.testEchoBodyPet(pet);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling BodyApi#testEchoBodyPet");
System.err.println("Status code: " + e.getCode());
System.err.println("Reason: " + e.getResponseBody());
System.err.println("Response headers: " + e.getResponseHeaders());
e.printStackTrace();
}
}
}
```
### Parameters
| Name | Type | Description | Notes |
|------------- | ------------- | ------------- | -------------|
| **pet** | [**Pet**](Pet.md)| Pet object that needs to be added to the store | [optional] |
### Return type
[**Pet**](Pet.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
| **200** | Successful operation | - |

View File

@@ -0,0 +1,14 @@
# Category
## Properties
| Name | Type | Description | Notes |
|------------ | ------------- | ------------- | -------------|
|**id** | **Long** | | [optional] |
|**name** | **String** | | [optional] |

View File

@@ -0,0 +1,77 @@
# PathApi
All URIs are relative to *http://localhost:3000*
| Method | HTTP request | Description |
|------------- | ------------- | -------------|
| [**testsPathStringPathStringIntegerPathInteger**](PathApi.md#testsPathStringPathStringIntegerPathInteger) | **GET** /path/string/{path_string}/integer/{path_integer} | Test path parameter(s) |
## testsPathStringPathStringIntegerPathInteger
> String testsPathStringPathStringIntegerPathInteger(pathString, pathInteger)
Test path parameter(s)
Test path parameter(s)
### Example
```java
// Import classes:
import org.openapitools.client.ApiClient;
import org.openapitools.client.ApiException;
import org.openapitools.client.Configuration;
import org.openapitools.client.models.*;
import org.openapitools.client.api.PathApi;
public class Example {
public static void main(String[] args) {
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("http://localhost:3000");
PathApi apiInstance = new PathApi(defaultClient);
String pathString = "pathString_example"; // String |
Integer pathInteger = 56; // Integer |
try {
String result = apiInstance.testsPathStringPathStringIntegerPathInteger(pathString, pathInteger);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling PathApi#testsPathStringPathStringIntegerPathInteger");
System.err.println("Status code: " + e.getCode());
System.err.println("Reason: " + e.getResponseBody());
System.err.println("Response headers: " + e.getResponseHeaders());
e.printStackTrace();
}
}
}
```
### Parameters
| Name | Type | Description | Notes |
|------------- | ------------- | ------------- | -------------|
| **pathString** | **String**| | |
| **pathInteger** | **Integer**| | |
### Return type
**String**
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: text/plain
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
| **200** | Successful operation | - |

View File

@@ -0,0 +1,28 @@
# Pet
## Properties
| Name | Type | Description | Notes |
|------------ | ------------- | ------------- | -------------|
|**id** | **Long** | | [optional] |
|**name** | **String** | | |
|**category** | [**Category**](Category.md) | | [optional] |
|**photoUrls** | **List&lt;String&gt;** | | |
|**tags** | [**List&lt;Tag&gt;**](Tag.md) | | [optional] |
|**status** | [**StatusEnum**](#StatusEnum) | pet status in the store | [optional] |
## Enum: StatusEnum
| Name | Value |
|---- | -----|
| AVAILABLE | &quot;available&quot; |
| PENDING | &quot;pending&quot; |
| SOLD | &quot;sold&quot; |

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