Add typescript-nestjs client generator (#8522)

* #3336 add nestjs generator

* #3336 add nestjs generator

* #3336 add nestjs generator

* #3336 add nestjs generator

* remove extra files from building

* Revert "remove extra files from building"

This reverts commit 7f80f961ef0cd0e50b9d2bb856a3703d5b821640.

* fix merge

* fix tests

* Add missing test client options provider for nestjs

* cleanup PRS

* fix compilation error

* remove groovy bin files;

* fix tests

* add samples

* update doc

* update samples

Co-authored-by: Victor Frank <vfrank@lumeris.com>
This commit is contained in:
William Cheng 2021-01-26 16:34:33 +08:00 committed by GitHub
parent fb1b62816f
commit f6c617d09f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
71 changed files with 4148 additions and 0 deletions

View File

@ -1244,6 +1244,30 @@
"Client: TypeScript" "Client: TypeScript"
] ]
}, },
{
"input": "typescript-nestjs-v6-petstore-not-provided-in-root-with-npm.sh",
"matches": [
"Client: TypeScript"
]
},
{
"input": "typescript-nestjs-v6-petstore-not-provided-in-root.sh",
"matches": [
"Client: TypeScript"
]
},
{
"input": "typescript-nestjs-v6-petstore-provided-in-root-with-npm.sh",
"matches": [
"Client: TypeScript"
]
},
{
"input": "typescript-nestjs-v6-petstore-provided-in-root.sh",
"matches": [
"Client: TypeScript"
]
},
{ {
"input": "typescript-node-petstore-with-npm.sh", "input": "typescript-node-petstore-with-npm.sh",
"matches": [ "matches": [

1
.gitignore vendored
View File

@ -31,6 +31,7 @@ packages/
.vscode/ .vscode/
**/.vs **/.vs
.factorypath .factorypath
.metals/*
.settings .settings

View File

@ -0,0 +1,9 @@
generatorName: typescript-nestjs
outputDir: samples/client/petstore/typescript-nestjs-v6-provided-in-root/builds/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
additionalProperties:
nestVersion: 6.0.0
"npmName": "@openapitools/typescript-nestjs-petstore"
"npmVersion": "1.0.0"
"npmRepository" : "https://skimdb.npmjs.com/registry"
"snapshot" : false

View File

@ -69,6 +69,7 @@ The following generators are available:
* [typescript-fetch](generators/typescript-fetch.md) * [typescript-fetch](generators/typescript-fetch.md)
* [typescript-inversify](generators/typescript-inversify.md) * [typescript-inversify](generators/typescript-inversify.md)
* [typescript-jquery](generators/typescript-jquery.md) * [typescript-jquery](generators/typescript-jquery.md)
* [typescript-nestjs (experimental)](generators/typescript-nestjs.md)
* [typescript-node](generators/typescript-node.md) * [typescript-node](generators/typescript-node.md)
* [typescript-redux-query](generators/typescript-redux-query.md) * [typescript-redux-query](generators/typescript-redux-query.md)
* [typescript-rxjs](generators/typescript-rxjs.md) * [typescript-rxjs](generators/typescript-rxjs.md)

View File

@ -0,0 +1,254 @@
---
title: Config Options for typescript-nestjs
sidebar_label: typescript-nestjs
---
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|enumNameSuffix|Suffix that will be appended to all enum names.| |Enum|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |PascalCase|
|fileNaming|Naming convention for the output files: 'camelCase', 'kebab-case'.| |camelCase|
|legacyDiscriminatorBehavior|Set to true for generators with better support for discriminators. (Python, Java, Go, PowerShell, C#have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
|modelFileSuffix|The suffix of the file of the generated model (model&lt;suffix&gt;.ts).| |null|
|modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name. Only change it if you provide your own run-time code for (de-)serialization of models| |original|
|modelSuffix|The suffix of the generated model.| |null|
|nestVersion|The version of Nestjs.| |6.0.0|
|npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null|
|npmRepository|Use this property to set an url your private npmRepo in the package.json| |null|
|npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0|
|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false|
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|serviceFileSuffix|The suffix of the file of the generated service (service&lt;suffix&gt;.ts).| |.service|
|serviceSuffix|The suffix of the generated service.| |Service|
|snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|stringEnums|Generate string enums instead of objects for enum values.| |false|
|supportsES6|Generate code that conforms to ES6.| |false|
|taggedUnions|Use discriminators to create tagged unions instead of extending interfaces.| |false|
|withInterfaces|Setting this property to true will generate interfaces next to the default class implementations.| |false|
## IMPORT MAPPING
| Type/Alias | Imports |
| ---------- | ------- |
## INSTANTIATION TYPES
| Type/Alias | Instantiated By |
| ---------- | --------------- |
|array|Array|
## LANGUAGE PRIMITIVES
<ul class="column-ul">
<li>Array</li>
<li>Blob</li>
<li>Boolean</li>
<li>Date</li>
<li>Double</li>
<li>Error</li>
<li>File</li>
<li>Float</li>
<li>Integer</li>
<li>Long</li>
<li>Map</li>
<li>Object</li>
<li>ReadonlyArray</li>
<li>Set</li>
<li>String</li>
<li>any</li>
<li>boolean</li>
<li>number</li>
<li>object</li>
<li>string</li>
</ul>
## RESERVED WORDS
<ul class="column-ul">
<li>abstract</li>
<li>await</li>
<li>boolean</li>
<li>break</li>
<li>byte</li>
<li>case</li>
<li>catch</li>
<li>char</li>
<li>class</li>
<li>const</li>
<li>continue</li>
<li>debugger</li>
<li>default</li>
<li>delete</li>
<li>do</li>
<li>double</li>
<li>else</li>
<li>enum</li>
<li>export</li>
<li>extends</li>
<li>false</li>
<li>final</li>
<li>finally</li>
<li>float</li>
<li>for</li>
<li>formParams</li>
<li>function</li>
<li>goto</li>
<li>headerParams</li>
<li>if</li>
<li>implements</li>
<li>import</li>
<li>in</li>
<li>instanceof</li>
<li>int</li>
<li>interface</li>
<li>let</li>
<li>long</li>
<li>native</li>
<li>new</li>
<li>null</li>
<li>package</li>
<li>private</li>
<li>protected</li>
<li>public</li>
<li>queryParameters</li>
<li>requestOptions</li>
<li>return</li>
<li>short</li>
<li>static</li>
<li>super</li>
<li>switch</li>
<li>synchronized</li>
<li>this</li>
<li>throw</li>
<li>transient</li>
<li>true</li>
<li>try</li>
<li>typeof</li>
<li>useFormData</li>
<li>var</li>
<li>varLocalDeferred</li>
<li>varLocalPath</li>
<li>void</li>
<li>volatile</li>
<li>while</li>
<li>with</li>
<li>yield</li>
</ul>
## FEATURE SET
### Client Modification Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasePath|✓|ToolingExtension
|Authorizations|✗|ToolingExtension
|UserAgent|✗|ToolingExtension
|MockServer|✗|ToolingExtension
### Data Type Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Custom|✗|OAS2,OAS3
|Int32|✓|OAS2,OAS3
|Int64|✓|OAS2,OAS3
|Float|✓|OAS2,OAS3
|Double|✓|OAS2,OAS3
|Decimal|✓|ToolingExtension
|String|✓|OAS2,OAS3
|Byte|✓|OAS2,OAS3
|Binary|✓|OAS2,OAS3
|Boolean|✓|OAS2,OAS3
|Date|✓|OAS2,OAS3
|DateTime|✓|OAS2,OAS3
|Password|✓|OAS2,OAS3
|File|✓|OAS2
|Array|✓|OAS2,OAS3
|Maps|✓|ToolingExtension
|CollectionFormat|✓|OAS2
|CollectionFormatMulti|✓|OAS2
|Enum|✓|OAS2,OAS3
|ArrayOfEnum|✓|ToolingExtension
|ArrayOfModel|✓|ToolingExtension
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|ArrayOfCollectionOfModel|✓|ToolingExtension
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|MapOfEnum|✓|ToolingExtension
|MapOfModel|✓|ToolingExtension
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|MapOfCollectionOfModel|✓|ToolingExtension
|MapOfCollectionOfEnum|✓|ToolingExtension
### Documentation Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Readme|✓|ToolingExtension
|Model|✓|ToolingExtension
|Api|✓|ToolingExtension
### Global Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Host|✓|OAS2,OAS3
|BasePath|✓|OAS2,OAS3
|Info|✓|OAS2,OAS3
|Schemes|✗|OAS2,OAS3
|PartialSchemes|✓|OAS2,OAS3
|Consumes|✓|OAS2
|Produces|✓|OAS2
|ExternalDocumentation|✓|OAS2,OAS3
|Examples|✓|OAS2,OAS3
|XMLStructureDefinitions|✗|OAS2,OAS3
|MultiServer|✗|OAS3
|ParameterizedServer|✗|OAS3
|ParameterStyling|✗|OAS3
|Callbacks|✗|OAS3
|LinkObjects|✗|OAS3
### Parameter Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Path|✓|OAS2,OAS3
|Query|✓|OAS2,OAS3
|Header|✓|OAS2,OAS3
|Body|✓|OAS2
|FormUnencoded|✓|OAS2
|FormMultipart|✓|OAS2
|Cookie|✓|OAS3
### Schema Support Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Simple|✓|OAS2,OAS3
|Composite|✓|OAS2,OAS3
|Polymorphism|✓|OAS2,OAS3
|Union|✗|OAS3
### Security Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasicAuth|✗|OAS2,OAS3
|ApiKey|✗|OAS2,OAS3
|OpenIDConnect|✗|OAS3
|BearerToken|✗|OAS3
|OAuth2_Implicit|✗|OAS2,OAS3
|OAuth2_Password|✗|OAS2,OAS3
|OAuth2_ClientCredentials|✗|OAS2,OAS3
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
### Wire Format Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|JSON|✓|OAS2,OAS3
|XML|✓|OAS2,OAS3
|PROTOBUF|✗|ToolingExtension
|Custom|✗|OAS2,OAS3

View File

@ -0,0 +1,552 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
import org.openapitools.codegen.meta.features.*;
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 static org.apache.commons.lang3.StringUtils.capitalize;
import static org.openapitools.codegen.utils.StringUtils.*;
public class TypeScriptNestjsClientCodegen extends AbstractTypeScriptClientCodegen {
private static final Logger LOGGER = LoggerFactory.getLogger(TypeScriptNestjsClientCodegen.class);
private static String CLASS_NAME_SUFFIX_PATTERN = "^[a-zA-Z0-9]*$";
private static String FILE_NAME_SUFFIX_PATTERN = "^[a-zA-Z0-9.-]*$";
public static final String NPM_REPOSITORY = "npmRepository";
public static final String WITH_INTERFACES = "withInterfaces";
public static final String TAGGED_UNIONS = "taggedUnions";
public static final String NEST_VERSION = "nestVersion";
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.";
protected String nestVersion = "6.0.0";
protected String npmRepository = null;
protected String serviceSuffix = "Service";
protected String serviceFileSuffix = ".service";
protected String modelSuffix = "";
protected String modelFileSuffix = "";
protected String fileNaming = "camelCase";
protected Boolean stringEnums = false;
private boolean taggedUnions = false;
public TypeScriptNestjsClientCodegen() {
super();
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
.stability(Stability.EXPERIMENTAL)
.build();
this.outputFolder = "generated-code/typescript-nestjs";
supportsMultipleInheritance = true;
embeddedTemplateDir = templateDir = "typescript-nestjs";
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(TAGGED_UNIONS,
"Use discriminators to create tagged unions instead of extending interfaces.",
this.taggedUnions));
this.cliOptions.add(new CliOption(NEST_VERSION, "The version of Nestjs.").defaultValue(this.nestVersion));
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)));
}
@Override
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) {
codegenModel.additionalPropertiesType = getTypeDeclaration(getAdditionalProperties(schema));
addImport(codegenModel, codegenModel.additionalPropertiesType);
}
@Override
public String getName() {
return "typescript-nestjs";
}
@Override
public String getHelp() {
return "Generates a TypeScript Nestjs 6.x client library.";
}
@Override
public void processOpts() {
super.processOpts();
supportingFiles.add(
new SupportingFile("models.mustache", modelPackage().replace('.', File.separatorChar), "models.ts"));
supportingFiles
.add(new SupportingFile("apis.mustache", apiPackage().replace('.', File.separatorChar), "api.ts"));
supportingFiles.add(new SupportingFile("index.mustache", getIndexDirectory(), "index.ts"));
supportingFiles.add(new SupportingFile("api.module.mustache", getIndexDirectory(), "api.module.ts"));
supportingFiles.add(new SupportingFile("configuration.mustache", getIndexDirectory(), "configuration.ts"));
supportingFiles.add(new SupportingFile("variables.mustache", getIndexDirectory(), "variables.ts"));
//supportingFiles.add(new SupportingFile("encoder.mustache", getIndexDirectory(), "encoder.ts"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("README.mustache", getIndexDirectory(), "README.md"));
// determine Nestjs version
SemVer nestVersion;
if (additionalProperties.containsKey(NEST_VERSION)) {
nestVersion = new SemVer(additionalProperties.get(NEST_VERSION).toString());
} else {
nestVersion = new SemVer(this.nestVersion);
LOGGER.info("generating code for Nestjs {} ...", nestVersion);
LOGGER.info(" (you can select the nestjs version by setting the additionalProperty nestVersion)");
}
if (additionalProperties.containsKey(NPM_NAME)) {
addNpmPackageGeneration(nestVersion);
}
if (additionalProperties.containsKey(STRING_ENUMS)) {
setStringEnums(Boolean.valueOf(additionalProperties.get(STRING_ENUMS).toString()));
additionalProperties.put("stringEnums", getStringEnums());
if (getStringEnums()) {
enumSuffix = "";
classEnumSeparator = "";
}
}
if (additionalProperties.containsKey(WITH_INTERFACES)) {
boolean withInterfaces = Boolean.parseBoolean(additionalProperties.get(WITH_INTERFACES).toString());
if (withInterfaces) {
apiTemplateFiles.put("apiInterface.mustache", "Interface.ts");
}
}
if (additionalProperties.containsKey(TAGGED_UNIONS)) {
taggedUnions = Boolean.parseBoolean(additionalProperties.get(TAGGED_UNIONS).toString());
}
additionalProperties.put(NEST_VERSION, nestVersion);
additionalProperties.put("injectionToken", nestVersion.atLeast("4.0.0") ? "InjectionToken" : "OpaqueToken");
additionalProperties.put("injectionTokenTyped", nestVersion.atLeast("4.0.0"));
additionalProperties.put("useHttpClient", nestVersion.atLeast("4.3.0"));
if (additionalProperties.containsKey(SERVICE_SUFFIX)) {
serviceSuffix = additionalProperties.get(SERVICE_SUFFIX).toString();
validateClassSuffixArgument("Service", serviceSuffix);
}
if (additionalProperties.containsKey(SERVICE_FILE_SUFFIX)) {
serviceFileSuffix = additionalProperties.get(SERVICE_FILE_SUFFIX).toString();
validateFileSuffixArgument("Service", serviceFileSuffix);
}
if (additionalProperties.containsKey(MODEL_SUFFIX)) {
modelSuffix = additionalProperties.get(MODEL_SUFFIX).toString();
validateClassSuffixArgument("Model", modelSuffix);
}
if (additionalProperties.containsKey(MODEL_FILE_SUFFIX)) {
modelFileSuffix = additionalProperties.get(MODEL_FILE_SUFFIX).toString();
validateFileSuffixArgument("Model", modelFileSuffix);
}
if (additionalProperties.containsKey(FILE_NAMING)) {
this.setFileNaming(additionalProperties.get(FILE_NAMING).toString());
}
}
private void addNpmPackageGeneration(SemVer nestVersion) {
if (additionalProperties.containsKey(NPM_REPOSITORY)) {
this.setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString());
}
additionalProperties.put("tsVersion", ">=3.6.0. <4.0.0");
//Files for building our lib
supportingFiles.add(new SupportingFile("package.mustache", getIndexDirectory(), "package.json"));
supportingFiles.add(new SupportingFile("tsconfig.build.mustache", getIndexDirectory(), "tsconfig.build.json"));
supportingFiles.add(new SupportingFile("tsconfig.mustache", getIndexDirectory(), "tsconfig.json"));
supportingFiles.add(new SupportingFile("tslint.mustache", getIndexDirectory(), "tslint.json"));
}
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;
}
@Override
public boolean isDataTypeFile(final String dataType) {
return dataType != null && dataType.equals("Blob");
}
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isFileSchema(p)) {
return "Blob";
} else {
return super.getTypeDeclaration(p);
}
}
@Override
public String getSchemaType(Schema p) {
String openAPIType = super.getSchemaType(p);
if (isLanguagePrimitive(openAPIType) || isLanguageGenericType(openAPIType)) {
return openAPIType;
}
applyLocalTypeMapping(openAPIType);
return openAPIType;
}
private String applyLocalTypeMapping(String type) {
if (typeMapping.containsKey(type)) {
type = typeMapping.get(type);
}
return type;
}
private boolean isLanguagePrimitive(String type) {
return languageSpecificPrimitives.contains(type);
}
private boolean isLanguageGenericType(String type) {
for (String genericType : languageGenericTypes) {
if (type.startsWith(genericType + "<")) {
return true;
}
}
return false;
}
@Override
public void postProcessParameter(CodegenParameter parameter) {
super.postProcessParameter(parameter);
parameter.dataType = applyLocalTypeMapping(parameter.dataType);
}
@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> operations, List<Object> allModels) {
Map<String, Object> objs = (Map<String, Object>) operations.get("operations");
// Add filename information for api imports
objs.put("apiFilename", getApiFilenameFromClassname(objs.get("classname").toString()));
List<CodegenOperation> ops = (List<CodegenOperation>) objs.get("operation");
boolean hasSomeFormParams = 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();
StringBuilder parameterName = new StringBuilder();
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++;
// Add the more complicated component instead of just the brace.
pathBuffer.append("${encodeURIComponent(String(");
break;
case '}':
// We exited curly braces, so track that.
insideCurly--;
// Add the more complicated component instead of just the brace.
CodegenParameter parameter = findPathParameterByName(op, parameterName.toString());
pathBuffer.append(toVarName(parameterName.toString()));
if (parameter != null && parameter.isDateTime) {
pathBuffer.append(".toISOString()");
}
pathBuffer.append("))}");
parameterName.setLength(0);
break;
default:
char nextChar = op.path.charAt(i);
if (insideCurly > 0) {
parameterName.append(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);
// Add additional filename information for model imports in the services
List<Map<String, Object>> imports = (List<Map<String, Object>>) operations.get("imports");
for (Map<String, Object> im : imports) {
im.put("filename", im.get("import"));
im.put("classname", im.get("classname"));
}
return operations;
}
/**
* Finds and returns a path parameter of an operation by its name
*
* @param operation the operation
* @param parameterName the name of the parameter
* @return param
*/
private CodegenParameter findPathParameterByName(CodegenOperation operation, String parameterName) {
for (CodegenParameter param : operation.pathParams) {
if (param.baseName.equals(parameterName)) {
return param;
}
}
return null;
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
Map<String, Object> result = super.postProcessModels(objs);
return postProcessModelsEnum(result);
}
@Override
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
Map<String, Object> result = super.postProcessAllModels(objs);
for (Map.Entry<String, Object> entry : result.entrySet()) {
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
if (taggedUnions) {
mo.put(TAGGED_UNIONS, true);
if (cm.discriminator != null && cm.children != null) {
for (CodegenModel child : cm.children) {
cm.imports.add(child.classname);
}
}
if (cm.parent != null) {
cm.imports.remove(cm.parent);
}
}
// Add additional filename information for imports
Set<String> parsedImports = parseImports(cm);
mo.put("tsImports", toTsImports(cm, parsedImports));
}
}
return result;
}
/**
* Parse imports
*/
private Set<String> parseImports(CodegenModel cm) {
Set<String> newImports = new HashSet<String>();
if (cm.imports.size() > 0) {
for (String name : cm.imports) {
if (name.indexOf(" | ") >= 0) {
String[] parts = name.split(" \\| ");
for (String s : parts) {
newImports.add(s);
}
} 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) {
return apiPackage() + "/" + toApiFilename(name);
}
@Override
public String toModelFilename(String name) {
return this.convertUsingFileNamingConvention(this.sanitizeName(name)) + modelFileSuffix;
}
@Override
public String toModelImport(String name) {
return modelPackage() + "/" + toModelFilename(name);
}
public String getNpmRepository() {
return npmRepository;
}
public void setNpmRepository(String npmRepository) {
this.npmRepository = npmRepository;
}
private String getApiFilenameFromClassname(String classname) {
String name = classname.substring(0, classname.length() - serviceSuffix.length());
return toApiFilename(name);
}
@Override
public String toModelName(String name) {
String modelName = super.toModelName(name);
if (modelSuffix.length() == 0 || modelName.endsWith(modelSuffix)) {
return modelName;
}
return modelName + modelSuffix;
}
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 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 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, true);
}
return name;
}
}

View File

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

View File

@ -0,0 +1,137 @@
## {{npmName}}@{{npmVersion}}
### Building
To install the required dependencies and to build the typescript sources run:
```
npm install
npm run build
```
#### General usage
In your Nestjs project:
```
// without configuring providers
import { ApiModule } from '{{npmName}}';
import { HttpModule } from '@nestjs/common';
@Module({
imports: [
ApiModule,
HttpModule
],
providers: []
})
export class AppModule {}
```
```
// configuring providers
import { ApiModule, Configuration, ConfigurationParameters } from '{{npmName}}';
export function apiConfigFactory (): Configuration => {
const params: ConfigurationParameters = {
// set configuration parameters here.
}
return new Configuration(params);
}
@Module({
imports: [ ApiModule.forRoot(apiConfigFactory) ],
declarations: [ AppComponent ],
providers: [],
bootstrap: [ AppComponent ]
})
export class AppModule {}
```
```
import { DefaultApi } from '{{npmName}}';
export class AppComponent {
constructor(private apiGateway: DefaultApi) { }
}
```
Note: The ApiModule a dynamic module and instantiated once app wide.
This is to ensure that all services are treated as singletons.
#### Using multiple swagger files / APIs / ApiModules
In order to use multiple `ApiModules` generated from different swagger files,
you can create an alias name when importing the modules
in order to avoid naming conflicts:
```
import { ApiModule } from 'my-api-path';
import { ApiModule as OtherApiModule } from 'my-other-api-path';
import { HttpModule } from '@nestjs/common';
@Module({
imports: [
ApiModule,
OtherApiModule,
HttpModule
]
})
export class AppModule {
}
```
### Set service base path
If different than the generated base path, during app bootstrap, you can provide the base path to your service.
```
import { BASE_PATH } from '{{npmName}}';
bootstrap(AppComponent, [
{ provide: BASE_PATH, useValue: 'https://your-web-service.com' },
]);
```
or
```
import { BASE_PATH } from '{{npmName}}';
@Module({
imports: [],
declarations: [ AppComponent ],
providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
```
#### Using @nestjs/cli
First extend your `src/environments/*.ts` files by adding the corresponding base path:
```
export const environment = {
production: false,
API_BASE_PATH: 'http://127.0.0.1:8080'
};
```
In the src/app/app.module.ts:
```
import { BASE_PATH } from '{{npmName}}';
import { environment } from '../environments/environment';
@Module({
declarations: [
AppComponent
],
imports: [ ],
providers: [
{
provide: 'BASE_PATH',
useValue: environment.API_BASE_PATH
}
]
})
export class AppModule { }
```

View File

@ -0,0 +1,32 @@
import { DynamicModule, HttpService, HttpModule, Module, Global } from '@nestjs/common';
import { Configuration } from './configuration';
import { BASE_PATH } from './variables';
{{#apiInfo}}
{{#apis}}
import { {{classname}} } from './{{importPath}}';
{{/apis}}
{{/apiInfo}}
@Global
@Module({
imports: [ HttpModule ],
exports: [
{{#apiInfo}}{{#apis}}{{classname}}{{#hasMore}},
{{/hasMore}}{{/apis}}{{/apiInfo}}
],
providers: [
{{#apiInfo}}{{#apis}}{{classname}}{{#hasMore}},
{{/hasMore}}{{/apis}}{{/apiInfo}}
]
})
export class ApiModule {
public static forRoot(configurationFactory: () => Configuration): DynamicModule {
return {
module: ApiModule,
providers: [ { provide: Configuration, useFactory: configurationFactory } ]
};
}
constructor( httpService: HttpService) { }
}

View File

@ -0,0 +1,227 @@
{{>licenseInfo}}
/* tslint:disable:no-unused-variable member-ordering */
import { HttpService, Inject, Injectable } from '@nestjs/common';
import { AxiosResponse } from 'axios';
import { Observable } from 'rxjs';
{{#imports}}
import { {{classname}} } from '../{{filename}}';
{{/imports}}
import { Configuration } from '../configuration';
import { COLLECTION_FORMATS } from '../variables';
{{#withInterfaces}}
import { {{classname}}Interface } from './{{classFilename}}Interface';
{{/withInterfaces}}
{{#operations}}
{{#description}}
/**
* {{&description}}
*/
{{/description}}
@Injectable()
{{#withInterfaces}}
export class {{classname}} implements {{classname}}Interface {
{{/withInterfaces}}
{{^withInterfaces}}
export class {{classname}} {
{{/withInterfaces}}
protected basePath = '{{{basePath}}}';
public defaultHeaders = new Map()
public configuration = new Configuration();
constructor(protected httpClient: HttpService, configuration: Configuration) {
this.configuration = configuration;
this.basePath = basePath || configuration.basePath || this.basePath;
}
/**
* @param consumes string[] mime-types
* @return true: consumes contains 'multipart/form-data', false: otherwise
*/
private canConsumeForm(consumes: string[]): boolean {
const form = 'multipart/form-data';
return consumes.includes(form);
}
{{#operation}}
/**
* {{summary}}
* {{notes}}
{{#allParams}}* @param {{paramName}} {{description}}
{{/allParams}}* @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.
*/
public {{nickname}}({{#allParams}}{{^isConstEnumParam}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/isConstEnumParam}}{{/allParams}}): Observable<AxiosResponse<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>>;
public {{nickname}}({{#allParams}}{{^isConstEnumParam}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/isConstEnumParam}}{{/allParams}}): Observable<any> {
{{#allParams}}
{{#required}}
{{#isConstEnumParam}}
let {{paramName}} = {{{dataType}}};
{{/isConstEnumParam}}
{{^isConstEnumParam}}
if ({{paramName}} === null || {{paramName}} === undefined) {
throw new Error('Required parameter {{paramName}} was null or undefined when calling {{nickname}}.');
}
{{/isConstEnumParam}}
{{/required}}
{{/allParams}}
{{#hasQueryParams}}
let queryParameters = {};
{{#queryParams}}
{{#isListContainer}}
if ({{paramName}}) {
{{#isCollectionFormatMulti}}
{{paramName}}.forEach((element) => {
queryParameters.append('{{baseName}}', <any>element);
})
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
queryParameters['{{baseName}}'] = {{paramName}}.join(COLLECTION_FORMATS['{{collectionFormat}}']);
{{/isCollectionFormatMulti}}
}
{{/isListContainer}}
{{^isListContainer}}
if ({{paramName}} !== undefined && {{paramName}} !== null) {
{{#isDateTime}}
queryParameters['{{baseName}}'] = <any>{{paramName}}.toISOString();
{{/isDateTime}}
{{^isDateTime}}
queryParameters['{{baseName}}'] <any>{{paramName}};
{{/isDateTime}}
}
{{/isListContainer}}
{{/queryParams}}
{{/hasQueryParams}}
let headers = this.defaultHeaders;
{{#headerParams}}
{{#isListContainer}}
if ({{paramName}}) {
headers['{{baseName}}'] = {{paramName}}.join(COLLECTION_FORMATS['{{collectionFormat}}']);
}
{{/isListContainer}}
{{^isListContainer}}
if ({{paramName}} !== undefined && {{paramName}} !== null) {
headers['{{baseName}}'] String({{paramName}});
}
{{/isListContainer}}
{{/headerParams}}
{{#authMethods}}
// authentication ({{name}}) required
{{#isApiKey}}
{{#isKeyInHeader}}
if (this.configuration.apiKeys["{{keyParamName}}"]) {
headers['{{keyParamName}}'] = this.configuration.apiKeys["{{keyParamName}}"];
}
{{/isKeyInHeader}}
{{#isKeyInQuery}}
if (this.configuration.apiKeys["{{keyParamName}}"]) {
queryParameters['{{keyParamName}}'] = this.configuration.apiKeys["{{keyParamName}}"];
}
{{/isKeyInQuery}}
{{/isApiKey}}
{{#isBasic}}
if (this.configuration.username || this.configuration.password) {
headers['Authorization'] = 'Basic ' + btoa(this.configuration.username + ':' + this.configuration.password);
}
{{/isBasic}}
{{#isOAuth}}
if (this.configuration.accessToken) {
const accessToken = typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: this.configuration.accessToken;
headers['Authorization'] = 'Bearer ' + accessToken;
}
{{/isOAuth}}
{{/authMethods}}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
{{#produces}}
'{{{mediaType}}}'{{#hasMore}},{{/hasMore}}
{{/produces}}
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
{{#consumes}}
'{{{mediaType}}}'{{#hasMore}},{{/hasMore}}
{{/consumes}}
];
{{#bodyParam}}
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected != undefined) {
headers['Content-Type'] = httpContentTypeSelected;
}
{{/bodyParam}}
{{#hasFormParams}}
const canConsumeForm = this.canConsumeForm(consumes);
let formParams: { append(param: string, value: any): void; };
let useForm = false;
let convertFormParamsToString = 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
useForm = canConsumeForm;
{{/isFile}}
{{/formParams}}
if (useForm) {
formParams = new FormData();
} else {
// formParams = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
}
{{#formParams}}
{{#isListContainer}}
if ({{paramName}}) {
{{#isCollectionFormatMulti}}
{{paramName}}.forEach((element) => {
formParams.append('{{baseName}}', <any>element);
})
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
formParams.append('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS['{{collectionFormat}}']));
{{/isCollectionFormatMulti}}
}
{{/isListContainer}}
{{^isListContainer}}
if ({{paramName}} !== undefined) {
formParams.append('{{baseName}}', <any>{{paramName}});
}
{{/isListContainer}}
{{/formParams}}
{{/hasFormParams}}
return this.httpClient.{{httpMethod}}{{^isResponseFile}}<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>{{/isResponseFile}}(`${this.basePath}{{{path}}}`,{{#isBodyAllowed}}
{{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}{{#hasFormParams}}convertFormParamsToString ? formParams.toString() : formParams{{/hasFormParams}}{{^hasFormParams}}null{{/hasFormParams}}{{/bodyParam}},{{/isBodyAllowed}}
{
{{#hasQueryParams}}
params: queryParameters,
{{/hasQueryParams}}
{{#isResponseFile}}
responseType: "blob",
{{/isResponseFile}}
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1,33 @@
{{>licenseInfo}}
import { Observable } from 'rxjs';
{{#imports}}
import { {{classname}} } from '../{{filename}}';
{{/imports}}
import { Configuration } from '../configuration';
{{#operations}}
{{#description}}
/**
* {{&description}}
*/
{{/description}}
export interface {{classname}}Interface {
defaultHeaders: {};
configuration: Configuration;
{{#operation}}
/**
* {{summary}}
* {{notes}}
{{#allParams}}* @param {{paramName}} {{description}}
{{/allParams}}*/
{{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}extraHttpRequestParams?: any): Observable<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}>;
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1,12 @@
{{#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

@ -0,0 +1,79 @@
export interface ConfigurationParameters {
apiKeys?: {[ key: string ]: string};
username?: string;
password?: string;
accessToken?: string | (() => string);
basePath?: string;
withCredentials?: boolean;
}
export class Configuration {
apiKeys?: {[ key: string ]: string};
username?: string;
password?: string;
accessToken?: string | (() => string);
basePath?: string;
withCredentials?: boolean;
constructor(configurationParameters: ConfigurationParameters = {}) {
this.apiKeys = configurationParameters.apiKeys;
this.username = configurationParameters.username;
this.password = configurationParameters.password;
this.accessToken = configurationParameters.accessToken;
this.basePath = configurationParameters.basePath;
this.withCredentials = configurationParameters.withCredentials;
}
/**
* Select the correct content-type to use for a request.
* Uses {@link Configuration#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;
}
let type = contentTypes.find(x => this.isJsonMime(x));
if (type === undefined) {
return contentTypes[0];
}
return type;
}
/**
* Select the correct accept content-type to use for a request.
* Uses {@link Configuration#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;
}
let type = accepts.find(x => 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');
}
}

View File

@ -0,0 +1,58 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" "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

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

View File

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

View File

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

View File

@ -0,0 +1,16 @@
{{>licenseInfo}}
{{#models}}
{{#model}}
{{#tsImports}}
import { {{classname}} } from './{{filename}}';
{{/tsImports}}
{{#description}}
/**
* {{{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

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

View File

@ -0,0 +1,20 @@
{{#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

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

View File

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

View File

@ -0,0 +1,30 @@
{{#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

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
{
"language": "ts",
"collection": "@nestjs/schematics",
"sourceRoot": "src"
}

View File

@ -0,0 +1,7 @@
{
"watch": ["src"],
"ext": "ts",
"ignore": ["src/**/*.spec.ts"],
"exec": "node --inspect-brk -r ts-node/register -r tsconfig-paths/register src/main.ts"
}

View File

@ -0,0 +1,5 @@
{
"watch": ["dist"],
"ext": "js",
"exec": "node dist/main"
}

View File

@ -0,0 +1,71 @@
{
"name": "{{{npmName}}}",
"version": "{{{npmVersion}}}",
"description": "REST client for {{{npmName}}}",
"author": "OpenAPI Generator Contributors",
"keywords": [
"swagger-client"
],
"license": "Unlicense",
"scripts": {
"build": "tsc -p tsconfig.build.json",
"build:clean": "rm -rf dist/ 2> /dev/null && tsc -p tsconfig.build.json",
"format": "prettier --write \"src/**/*.ts\"",
"start": "ts-node -r tsconfig-paths/register src/main.ts",
"start:dev": "concurrently --handle-input \"wait-on dist/main.js && nodemon\" \"tsc -w -p tsconfig.build.json\" ",
"start:debug": "nodemon --config nodemon-debug.json",
"prestart:prod": "rimraf dist && npm run build",
"start:prod": "node dist/main.js",
"lint": "tslint -p tsconfig.json -c tslint.json",
"lint:fix": "tslint -p tsconfig.json -c tslint.json --fix --force",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^{{nestVersion}}",
"@nestjs/core": "^{{nestVersion}}",
"@nestjs/platform-express": "^{{nestVersion}}",
"reflect-metadata": "^0.1.13",
"rimraf": "^2.6.3",
"rxjs": "^6.5.2"
},
"devDependencies": {
"@nestjs/testing": "~{{nestVersion}}",
"@types/express": "^4.16.0",
"@types/jest": "^24.0.15",
"@types/node": "^12.6.1",
"@types/supertest": "^2.0.8",
"concurrently": "^4.1.1",
"nodemon": "^1.19.1",
"prettier": "^1.18.2",
"supertest": "^4.0.2",
"ts-jest": "24.0.2",
"ts-node": "8.3.0",
"tsconfig-paths": "3.8.0",
"tslint": "5.18.0",
"typescript": "3.5.3",
"wait-on": "^3.2.0"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}{{#npmRepository}},{{/npmRepository}}
{{#npmRepository}}
"publishConfig": {
"registry": "{{{npmRepository}}}"
}
{{/npmRepository}}
}

View File

@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"exclude": [
"node_modules",
"test",
"dist",
"**/*spec.ts"
]
}

View File

@ -0,0 +1,22 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "{{#supportsES6}}es6{{/supportsES6}}{{^supportsES6}}es5{{/supportsES6}}",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true
},
"exclude": [
"node_modules",
"dist"
],
"filesGlob": [
"./model/*.ts",
"./api/*.ts"
]
}

View File

@ -0,0 +1,18 @@
{
"defaultSeverity": "error",
"extends": ["tslint:recommended"],
"jsRules": {
"no-unused-expression": true
},
"rules": {
"quotemark": [true, "single"],
"member-access": [false],
"ordered-imports": [false],
"max-line-length": [true, 150],
"member-ordering": [false],
"interface-name": [false],
"arrow-parens": false,
"object-literal-sort-keys": false
},
"rulesDirectory": []
}

View File

@ -0,0 +1,7 @@
export const COLLECTION_FORMATS = {
'csv': ',',
'tsv': ' ',
'ssv': ' ',
'pipes': '|'
}

View File

@ -0,0 +1,92 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* 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.options;
import com.google.common.collect.ImmutableMap;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen;
import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen;
import java.util.Map;
public class TypeScriptNestjsClientOptionsProvider implements OptionsProvider {
public static final String SUPPORTS_ES6_VALUE = "false";
public static final String NULL_SAFE_ADDITIONAL_PROPS_VALUE = "false";
public static final String ENUM_NAME_SUFFIX = "Enum";
public static final String STRING_ENUMS_VALUE = "false";
public static final String SORT_PARAMS_VALUE = "false";
public static final String SORT_MODEL_PROPERTIES_VALUE = "false";
public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
public static final String ENUM_PROPERTY_NAMING_VALUE = "PascalCase";
public static final String MODEL_PROPERTY_NAMING_VALUE = "camelCase";
private static final String NMP_NAME = "npmName";
private static final String NMP_VERSION = "1.1.2";
private static final String NPM_REPOSITORY = "https://registry.npmjs.org";
public static final String ALLOW_UNICODE_IDENTIFIERS_VALUE = "false";
public static final String NEST_VERSION = "6";
public static final String PREPEND_FORM_OR_BODY_PARAMETERS_VALUE = "true";
public static final String FILE_NAMING_VALUE = "camelCase";
public static final String API_MODULE_PREFIX = "";
public static String SERVICE_SUFFIX = "Service";
public static String SERVICE_FILE_SUFFIX = ".service";
public static String MODEL_SUFFIX = "";
public static String MODEL_FILE_SUFFIX = "";
@Override
public String getLanguage() {
return "typescript-nestjs";
}
@Override
public Map<String, String> createOptions() {
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
return builder.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE)
.put(CodegenConstants.SORT_MODEL_PROPERTIES_BY_REQUIRED_FLAG, SORT_MODEL_PROPERTIES_VALUE)
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
.put(CodegenConstants.ENUM_PROPERTY_NAMING, ENUM_PROPERTY_NAMING_VALUE)
.put(CodegenConstants.MODEL_PROPERTY_NAMING, MODEL_PROPERTY_NAMING_VALUE)
.put(CodegenConstants.SUPPORTS_ES6, SUPPORTS_ES6_VALUE)
.put(AbstractTypeScriptClientCodegen.NULL_SAFE_ADDITIONAL_PROPS, NULL_SAFE_ADDITIONAL_PROPS_VALUE)
.put(CodegenConstants.ENUM_NAME_SUFFIX, ENUM_NAME_SUFFIX)
.put(TypeScriptNestjsClientCodegen.STRING_ENUMS, STRING_ENUMS_VALUE)
.put(TypeScriptNestjsClientCodegen.NPM_NAME, NMP_NAME)
.put(TypeScriptNestjsClientCodegen.NPM_VERSION, NMP_VERSION)
.put(TypeScriptNestjsClientCodegen.SNAPSHOT, Boolean.FALSE.toString())
.put(TypeScriptNestjsClientCodegen.WITH_INTERFACES, Boolean.FALSE.toString())
//.put(TypeScriptNestjsClientCodegen.USE_SINGLE_REQUEST_PARAMETER, Boolean.FALSE.toString())
//.put(TypeScriptNestjsClientCodegen.PROVIDED_IN_ROOT, Boolean.FALSE.toString())
.put(TypeScriptNestjsClientCodegen.TAGGED_UNIONS, Boolean.FALSE.toString())
.put(TypeScriptNestjsClientCodegen.NPM_REPOSITORY, NPM_REPOSITORY)
.put(TypeScriptNestjsClientCodegen.NEST_VERSION, NEST_VERSION)
//.put(TypeScriptNestjsClientCodegen.API_MODULE_PREFIX, API_MODULE_PREFIX)
.put(TypeScriptNestjsClientCodegen.SERVICE_SUFFIX, SERVICE_SUFFIX)
.put(TypeScriptNestjsClientCodegen.SERVICE_FILE_SUFFIX, SERVICE_FILE_SUFFIX)
.put(TypeScriptNestjsClientCodegen.MODEL_SUFFIX, MODEL_SUFFIX)
.put(TypeScriptNestjsClientCodegen.MODEL_FILE_SUFFIX, MODEL_FILE_SUFFIX)
.put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE)
.put(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, PREPEND_FORM_OR_BODY_PARAMETERS_VALUE)
.put(CodegenConstants.LEGACY_DISCRIMINATOR_BEHAVIOR, "true")
.put(CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT, "true")
.put(TypeScriptNestjsClientCodegen.FILE_NAMING, FILE_NAMING_VALUE)
.build();
}
@Override
public boolean isServer() {
return false;
}
}

View File

@ -0,0 +1,135 @@
package org.openapitools.codegen.typescript.typescriptnestjs;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen;
import org.testng.Assert;
import org.testng.annotations.Test;
public class TypeScriptNestjsClientCodegenTest {
@Test
public void testModelFileSuffix() {
TypeScriptNestjsClientCodegen codegen = new TypeScriptNestjsClientCodegen();
codegen.additionalProperties().put("modelFileSuffix", "MySuffix");
codegen.additionalProperties().put("modelSuffix", "MySuffix");
codegen.processOpts();
Assert.assertEquals("testNameMySuffix", codegen.toModelFilename("testName"));
}
@Test
public void testOperationIdParser() {
OpenAPI openAPI = TestUtils.createOpenAPI();
Operation operation1 = new Operation().operationId("123_test_@#$%_special_tags").responses(new ApiResponses().addApiResponse("201", new ApiResponse().description("OK")));
openAPI.path("another-fake/dummy/", new PathItem().get(operation1));
final TypeScriptNestjsClientCodegen codegen = new TypeScriptNestjsClientCodegen();
codegen.setOpenAPI(openAPI);
CodegenOperation co1 = codegen.fromOperation("/another-fake/dummy/", "get", operation1, null);
org.testng.Assert.assertEquals(co1.operationId, "_123testSpecialTags");
}
@Test
public void testSnapshotVersion() {
OpenAPI openAPI = TestUtils.createOpenAPI();
TypeScriptNestjsClientCodegen codegen = new TypeScriptNestjsClientCodegen();
codegen.additionalProperties().put("npmName", "@openapi/typescript-nestjs-petstore");
codegen.additionalProperties().put("snapshot", true);
codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT");
codegen.processOpts();
codegen.preprocessOpenAPI(openAPI);
Assert.assertTrue(codegen.getNpmVersion().matches("^1.0.0-SNAPSHOT.[0-9]{12}$"));
codegen = new TypeScriptNestjsClientCodegen();
codegen.additionalProperties().put("npmName", "@openapi/typescript-nestjs-petstore");
codegen.additionalProperties().put("snapshot", true);
codegen.additionalProperties().put("npmVersion", "3.0.0-M1");
codegen.processOpts();
codegen.preprocessOpenAPI(openAPI);
Assert.assertTrue(codegen.getNpmVersion().matches("^3.0.0-M1-SNAPSHOT.[0-9]{12}$"));
}
@Test
public void testWithoutSnapshotVersion() {
OpenAPI openAPI = TestUtils.createOpenAPI();
TypeScriptNestjsClientCodegen codegen = new TypeScriptNestjsClientCodegen();
codegen.additionalProperties().put("npmName", "@openapi/typescript-nestjs-petstore");
codegen.additionalProperties().put("snapshot", false);
codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT");
codegen.processOpts();
codegen.preprocessOpenAPI(openAPI);
Assert.assertTrue(codegen.getNpmVersion().matches("^1.0.0-SNAPSHOT$"));
codegen = new TypeScriptNestjsClientCodegen();
codegen.additionalProperties().put("npmName", "@openapi/typescript-nestjs-petstore");
codegen.additionalProperties().put("snapshot", false);
codegen.additionalProperties().put("npmVersion", "3.0.0-M1");
codegen.processOpts();
codegen.preprocessOpenAPI(openAPI);
Assert.assertTrue(codegen.getNpmVersion().matches("^3.0.0-M1$"));
}
@Test
public void testRemovePrefixSuffix() {
TypeScriptNestjsClientCodegen codegen = new TypeScriptNestjsClientCodegen();
// simple noop test
Assert.assertEquals("TestName", codegen.removeModelPrefixSuffix("TestName"));
codegen.setModelNamePrefix("abc");
codegen.setModelNameSuffix("def");
codegen.additionalProperties().put("modelSuffix", "Ghi");
codegen.processOpts();
Assert.assertEquals("TestName", codegen.removeModelPrefixSuffix("TestName"));
Assert.assertEquals("TestName", codegen.removeModelPrefixSuffix("TestNameGhi"));
Assert.assertEquals("TestNameghi", codegen.removeModelPrefixSuffix("TestNameghi"));
Assert.assertEquals("abcTestName", codegen.removeModelPrefixSuffix("abcTestName"));
Assert.assertEquals("TestName", codegen.removeModelPrefixSuffix("AbcTestName"));
Assert.assertEquals("AbcTestName", codegen.removeModelPrefixSuffix("AbcAbcTestName"));
Assert.assertEquals("TestName", codegen.removeModelPrefixSuffix("TestNameDef"));
Assert.assertEquals("TestNamedef", codegen.removeModelPrefixSuffix("TestNamedef"));
Assert.assertEquals("TestNamedefghi", codegen.removeModelPrefixSuffix("TestNamedefghi"));
Assert.assertEquals("TestNameDefghi", codegen.removeModelPrefixSuffix("TestNameDefghi"));
Assert.assertEquals("TestName", codegen.removeModelPrefixSuffix("TestNameDefGhi"));
}
@Test
public void testSchema() {
TypeScriptNestjsClientCodegen codegen = new TypeScriptNestjsClientCodegen();
ComposedSchema composedSchema = new ComposedSchema();
Schema<Object> schema1 = new Schema<>();
schema1.set$ref("SchemaOne");
Schema<Object> schema2 = new Schema<>();
schema2.set$ref("SchemaTwo");
Schema<Object> schema3 = new Schema<>();
schema3.set$ref("SchemaThree");
composedSchema.addAnyOfItem(schema1);
composedSchema.addAnyOfItem(schema2);
composedSchema.addAnyOfItem(schema3);
String schemaType = codegen.getSchemaType(composedSchema);
Assert.assertEquals(schemaType, "SchemaOne | SchemaTwo | SchemaThree");
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.typescript.typescriptnestjs;
import org.openapitools.codegen.AbstractOptionsTest;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen;
import org.openapitools.codegen.options.TypeScriptNestjsClientOptionsProvider;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
public class TypeScriptNestjsClientOptionsTest extends AbstractOptionsTest {
private TypeScriptNestjsClientCodegen clientCodegen = mock(TypeScriptNestjsClientCodegen.class, mockSettings);
public TypeScriptNestjsClientOptionsTest() {
super(new TypeScriptNestjsClientOptionsProvider());
}
@Override
protected CodegenConfig getCodegenConfig() {
return clientCodegen;
}
@SuppressWarnings("unused")
@Override
protected void verifyOptions() {
verify(clientCodegen).setSortParamsByRequiredFlag(Boolean.valueOf(TypeScriptNestjsClientOptionsProvider.SORT_PARAMS_VALUE));
verify(clientCodegen).setModelPropertyNaming(TypeScriptNestjsClientOptionsProvider.MODEL_PROPERTY_NAMING_VALUE);
verify(clientCodegen).setSupportsES6(Boolean.valueOf(TypeScriptNestjsClientOptionsProvider.SUPPORTS_ES6_VALUE));
verify(clientCodegen).setStringEnums(Boolean.parseBoolean(TypeScriptNestjsClientOptionsProvider.STRING_ENUMS_VALUE));
verify(clientCodegen).setPrependFormOrBodyParameters(Boolean.valueOf(TypeScriptNestjsClientOptionsProvider.PREPEND_FORM_OR_BODY_PARAMETERS_VALUE));
}
}

View File

@ -0,0 +1,236 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.typescript.typescriptnestjs;
import com.google.common.collect.Sets;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.parser.util.SchemaTypeUtil;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen;
import org.testng.Assert;
import org.testng.annotations.Test;
@SuppressWarnings("static-method")
public class TypeScriptNestjsModelTest {
@Test(description = "convert a simple TypeScript Nestjs model")
public void simpleModelTest() {
final Schema model = new Schema()
.description("a sample model")
.addProperties("id", new IntegerSchema().format(SchemaTypeUtil.INTEGER64_FORMAT))
.addProperties("name", new StringSchema())
.addProperties("createdAt", new DateTimeSchema())
.addProperties("birthDate", new DateSchema())
.addRequiredItem("id")
.addRequiredItem("name");
final DefaultCodegen codegen = new TypeScriptNestjsClientCodegen();
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model);
codegen.setOpenAPI(openAPI);
final CodegenModel cm = codegen.fromModel("sample", model);
Assert.assertEquals(cm.name, "sample");
Assert.assertEquals(cm.classname, "Sample");
Assert.assertEquals(cm.description, "a sample model");
Assert.assertEquals(cm.vars.size(), 4);
final CodegenProperty property1 = cm.vars.get(0);
Assert.assertEquals(property1.baseName, "id");
Assert.assertEquals(property1.dataType, "number");
Assert.assertEquals(property1.name, "id");
Assert.assertEquals(property1.defaultValue, "undefined");
Assert.assertEquals(property1.baseType, "number");
Assert.assertTrue(property1.required);
Assert.assertFalse(property1.isContainer);
final CodegenProperty property2 = cm.vars.get(1);
Assert.assertEquals(property2.baseName, "name");
Assert.assertEquals(property2.dataType, "string");
Assert.assertEquals(property2.name, "name");
Assert.assertEquals(property2.defaultValue, "undefined");
Assert.assertEquals(property2.baseType, "string");
Assert.assertTrue(property2.required);
Assert.assertFalse(property2.isContainer);
final CodegenProperty property3 = cm.vars.get(2);
Assert.assertEquals(property3.baseName, "createdAt");
Assert.assertEquals(property3.complexType, null);
Assert.assertEquals(property3.dataType, "string");
Assert.assertEquals(property3.name, "createdAt");
Assert.assertEquals(property3.baseType, "string");
Assert.assertEquals(property3.defaultValue, "undefined");
Assert.assertFalse(property3.required);
Assert.assertFalse(property3.isContainer);
final CodegenProperty property4 = cm.vars.get(3);
Assert.assertEquals(property4.baseName, "birthDate");
Assert.assertEquals(property4.complexType, null);
Assert.assertEquals(property4.dataType, "string");
Assert.assertEquals(property4.name, "birthDate");
Assert.assertEquals(property4.baseType, "string");
Assert.assertEquals(property4.defaultValue, "undefined");
Assert.assertFalse(property4.required);
Assert.assertFalse(property4.isContainer);
}
@Test(description = "convert a model with list property")
public void listPropertyTest() {
final Schema schema = new Schema()
.description("a sample model")
.addProperties("id", new IntegerSchema().format(SchemaTypeUtil.INTEGER64_FORMAT))
.addProperties("urls", new ArraySchema().items(new StringSchema()))
.addRequiredItem("id");
final DefaultCodegen codegen = new TypeScriptNestjsClientCodegen();
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", schema);
codegen.setOpenAPI(openAPI);
final CodegenModel cm = codegen.fromModel("sample", schema);
Assert.assertEquals(cm.name, "sample");
Assert.assertEquals(cm.classname, "Sample");
Assert.assertEquals(cm.description, "a sample model");
Assert.assertEquals(cm.vars.size(), 2);
final CodegenProperty property1 = cm.vars.get(0);
Assert.assertEquals(property1.baseName, "id");
Assert.assertEquals(property1.dataType, "number");
Assert.assertEquals(property1.name, "id");
Assert.assertEquals(property1.defaultValue, "undefined");
Assert.assertEquals(property1.baseType, "number");
Assert.assertTrue(property1.required);
Assert.assertFalse(property1.isContainer);
final CodegenProperty property2 = cm.vars.get(1);
Assert.assertEquals(property2.baseName, "urls");
Assert.assertEquals(property2.dataType, "Array<string>");
Assert.assertEquals(property2.name, "urls");
Assert.assertEquals(property2.baseType, "Array");
Assert.assertFalse(property2.required);
}
@Test(description = "convert a model with complex property")
public void complexPropertyTest() {
final Schema schema = new Schema()
.description("a sample model")
.addProperties("children", new Schema().$ref("#/definitions/Children"));
final DefaultCodegen codegen = new TypeScriptNestjsClientCodegen();
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", schema);
codegen.setOpenAPI(openAPI);
final CodegenModel cm = codegen.fromModel("sample", schema);
Assert.assertEquals(cm.name, "sample");
Assert.assertEquals(cm.classname, "Sample");
Assert.assertEquals(cm.description, "a sample model");
Assert.assertEquals(cm.vars.size(), 1);
final CodegenProperty property1 = cm.vars.get(0);
Assert.assertEquals(property1.baseName, "children");
Assert.assertEquals(property1.dataType, "Children");
Assert.assertEquals(property1.name, "children");
Assert.assertEquals(property1.defaultValue, "undefined");
Assert.assertEquals(property1.baseType, "Children");
Assert.assertFalse(property1.required);
}
@Test(description = "convert a model with complex list property")
public void complexListPropertyTest() {
final Schema schema = new Schema()
.description("a sample model")
.addProperties("children", new ArraySchema()
.items(new Schema().$ref("#/definitions/Children")));
final DefaultCodegen codegen = new TypeScriptNestjsClientCodegen();
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", schema);
codegen.setOpenAPI(openAPI);
final CodegenModel cm = codegen.fromModel("sample", schema);
Assert.assertEquals(cm.name, "sample");
Assert.assertEquals(cm.classname, "Sample");
Assert.assertEquals(cm.description, "a sample model");
Assert.assertEquals(cm.vars.size(), 1);
final CodegenProperty property1 = cm.vars.get(0);
Assert.assertEquals(property1.baseName, "children");
Assert.assertEquals(property1.complexType, "Children");
Assert.assertEquals(property1.dataType, "Array<Children>");
Assert.assertEquals(property1.name, "children");
Assert.assertEquals(property1.baseType, "Array");
Assert.assertFalse(property1.required);
}
@Test(description = "convert an array model")
public void arrayModelTest() {
final Schema schema = new ArraySchema()
.items(new Schema().$ref("#/definitions/Children"))
.description("an array model");
final DefaultCodegen codegen = new TypeScriptNestjsClientCodegen();
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", schema);
codegen.setOpenAPI(openAPI);
final CodegenModel cm = codegen.fromModel("sample", schema);
Assert.assertEquals(cm.name, "sample");
Assert.assertEquals(cm.classname, "Sample");
Assert.assertEquals(cm.description, "an array model");
Assert.assertEquals(cm.vars.size(), 0);
}
@Test(description = "convert a map model")
public void mapModelTest() {
final Schema schema = new Schema()
.description("a map model")
.additionalProperties(new Schema().$ref("#/definitions/Children"));
final DefaultCodegen codegen = new TypeScriptNestjsClientCodegen();
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", schema);
codegen.setOpenAPI(openAPI);
final CodegenModel cm = codegen.fromModel("sample", schema);
Assert.assertEquals(cm.name, "sample");
Assert.assertEquals(cm.classname, "Sample");
Assert.assertEquals(cm.description, "a map model");
Assert.assertEquals(cm.vars.size(), 0);
Assert.assertEquals(cm.imports.size(), 1);
Assert.assertEquals(cm.additionalPropertiesType, "Children");
Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1);
}
@Test(description = "convert a model with a name starting with decimal")
public void beginDecimalNameTest() {
final Schema schema = new Schema()
.description("a model with a name starting with decimal")
.addProperties("1list", new StringSchema())
.addRequiredItem("1list");
final DefaultCodegen codegen = new TypeScriptNestjsClientCodegen();
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", schema);
codegen.setOpenAPI(openAPI);
final CodegenModel cm = codegen.fromModel("sample", schema);
Assert.assertEquals(cm.name, "sample");
Assert.assertEquals(cm.classname, "Sample");
Assert.assertEquals(cm.vars.size(), 1);
final CodegenProperty property = cm.vars.get(0);
Assert.assertEquals(property.baseName, "1list");
Assert.assertEquals(property.dataType, "string");
Assert.assertEquals(property.name, "_1list");
Assert.assertEquals(property.defaultValue, "undefined");
Assert.assertEquals(property.baseType, "string");
Assert.assertTrue(property.required);
Assert.assertFalse(property.isContainer);
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.typescript.typescriptnestjs;
import org.openapitools.codegen.AbstractIntegrationTest;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen;
import org.openapitools.codegen.testutils.IntegrationTestPathsConfig;
import java.util.HashMap;
import java.util.Map;
public class TypescriptNestjsAdditionalPropertiesIntegrationTest extends AbstractIntegrationTest {
@Override
protected CodegenConfig getCodegenConfig() {
return new TypeScriptNestjsClientCodegen();
}
@Override
protected Map<String, String> configProperties() {
Map<String, String> properties = new HashMap<>();
properties.put("npmName", "additionalPropertiesTest");
properties.put("npmVersion", "1.0.2");
properties.put("snapshot", "false");
return properties;
}
@Override
protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() {
return new IntegrationTestPathsConfig("typescript/additional-properties");
}
}

View File

@ -0,0 +1,52 @@
package org.openapitools.codegen.typescript.typescriptnestjs;
import io.swagger.v3.oas.models.OpenAPI;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen;
import org.testng.Assert;
import org.testng.annotations.Test;
public class TypescriptNestjsApiVersionTest {
@Test(description = "tests if API version specification is used if no version is provided in additional properties")
public void testWithApiVersion() {
final TypeScriptNestjsClientCodegen codegen = new TypeScriptNestjsClientCodegen();
codegen.additionalProperties().put("npmName", "just-a-test");
OpenAPI api = TestUtils.createOpenAPI();
codegen.processOpts();
codegen.preprocessOpenAPI(api);
Assert.assertEquals(codegen.getNpmVersion(), "1.0.7");
}
@Test(description = "tests if npmVersion additional property is used")
public void testWithNpmVersion() {
final TypeScriptNestjsClientCodegen codegen = new TypeScriptNestjsClientCodegen();
codegen.additionalProperties().put("npmName", "just-a-test");
codegen.additionalProperties().put("npmVersion", "2.0.0");
OpenAPI api = TestUtils.createOpenAPI();
codegen.processOpts();
codegen.preprocessOpenAPI(api);
Assert.assertEquals(codegen.getNpmVersion(), "2.0.0");
}
@Test(description = "tests if default version is used when neither OpenAPI version nor npmVersion additional property has been provided")
public void testWithoutApiVersion() {
final TypeScriptNestjsClientCodegen codegen = new TypeScriptNestjsClientCodegen();
codegen.additionalProperties().put("npmName", "just-a-test");
OpenAPI api = TestUtils.createOpenAPI();
api.getInfo().setVersion(null);
codegen.processOpts();
codegen.preprocessOpenAPI(api);
Assert.assertEquals(codegen.getNpmVersion(), "1.0.0");
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.typescript.typescriptnestjs;
import org.openapitools.codegen.AbstractIntegrationTest;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen;
import org.openapitools.codegen.testutils.IntegrationTestPathsConfig;
import java.util.HashMap;
import java.util.Map;
public class TypescriptNestjsArrayAndObjectIntegrationTest extends AbstractIntegrationTest {
@Override
protected CodegenConfig getCodegenConfig() {
return new TypeScriptNestjsClientCodegen();
}
@Override
protected Map<String, String> configProperties() {
Map<String, String> properties = new HashMap<>();
properties.put("npmName", "arrayAndAnyTest");
properties.put("npmVersion", "1.0.2");
properties.put("snapshot", "false");
return properties;
}
@Override
protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() {
return new IntegrationTestPathsConfig("typescript/array-and-object");
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.typescript.typescriptnestjs;
import org.openapitools.codegen.AbstractIntegrationTest;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen;
import org.openapitools.codegen.testutils.IntegrationTestPathsConfig;
import java.util.HashMap;
import java.util.Map;
public class TypescriptNestjsPestoreIntegrationTest extends AbstractIntegrationTest {
@Override
protected CodegenConfig getCodegenConfig() {
return new TypeScriptNestjsClientCodegen();
}
@Override
protected Map<String, String> configProperties() {
Map<String, String> properties = new HashMap<>();
properties.put("npmName", "petstore-integration-test");
properties.put("npmVersion", "1.0.3");
properties.put("snapshot", "false");
return properties;
}
@Override
protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() {
return new IntegrationTestPathsConfig("typescript/petstore");
}
}

View File

@ -1225,6 +1225,8 @@
<module>samples/client/petstore/typescript-axios/tests/default</module> <module>samples/client/petstore/typescript-axios/tests/default</module>
<module>samples/client/petstore/typescript-node/npm</module> <module>samples/client/petstore/typescript-node/npm</module>
<module>samples/client/petstore/typescript-rxjs/builds/with-npm-version</module> <module>samples/client/petstore/typescript-rxjs/builds/with-npm-version</module>
<!-- TODO comment out below when the test for typescript-nestjs is ready
<module>samples/client/petstore/typescript-nestjs-v6-provided-in-root</module>-->
<!-- comment out due to error `npm run build` <!-- comment out due to error `npm run build`
<module>samples/client/petstore/typescript-jquery/npm</module>--> <module>samples/client/petstore/typescript-jquery/npm</module>-->
<!--<module>samples/client/petstore/typescript-angular-v2/npm</module>--> <!--<module>samples/client/petstore/typescript-angular-v2/npm</module>-->

View File

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

View File

@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@ -0,0 +1,22 @@
.gitignore
README.md
api.module.ts
api/api.ts
api/pet.service.ts
api/store.service.ts
api/user.service.ts
configuration.ts
git_push.sh
index.ts
model/apiResponse.ts
model/category.ts
model/models.ts
model/order.ts
model/pet.ts
model/tag.ts
model/user.ts
package.json
tsconfig.build.json
tsconfig.json
tslint.json
variables.ts

View File

@ -0,0 +1,137 @@
## @openapitools/typescript-nestjs-petstore@1.0.0
### Building
To install the required dependencies and to build the typescript sources run:
```
npm install
npm run build
```
#### General usage
In your Nestjs project:
```
// without configuring providers
import { ApiModule } from '@openapitools/typescript-nestjs-petstore';
import { HttpModule } from '@nestjs/common';
@Module({
imports: [
ApiModule,
HttpModule
],
providers: []
})
export class AppModule {}
```
```
// configuring providers
import { ApiModule, Configuration, ConfigurationParameters } from '@openapitools/typescript-nestjs-petstore';
export function apiConfigFactory (): Configuration => {
const params: ConfigurationParameters = {
// set configuration parameters here.
}
return new Configuration(params);
}
@Module({
imports: [ ApiModule.forRoot(apiConfigFactory) ],
declarations: [ AppComponent ],
providers: [],
bootstrap: [ AppComponent ]
})
export class AppModule {}
```
```
import { DefaultApi } from '@openapitools/typescript-nestjs-petstore';
export class AppComponent {
constructor(private apiGateway: DefaultApi) { }
}
```
Note: The ApiModule a dynamic module and instantiated once app wide.
This is to ensure that all services are treated as singletons.
#### Using multiple swagger files / APIs / ApiModules
In order to use multiple `ApiModules` generated from different swagger files,
you can create an alias name when importing the modules
in order to avoid naming conflicts:
```
import { ApiModule } from 'my-api-path';
import { ApiModule as OtherApiModule } from 'my-other-api-path';
import { HttpModule } from '@nestjs/common';
@Module({
imports: [
ApiModule,
OtherApiModule,
HttpModule
]
})
export class AppModule {
}
```
### Set service base path
If different than the generated base path, during app bootstrap, you can provide the base path to your service.
```
import { BASE_PATH } from '@openapitools/typescript-nestjs-petstore';
bootstrap(AppComponent, [
{ provide: BASE_PATH, useValue: 'https://your-web-service.com' },
]);
```
or
```
import { BASE_PATH } from '@openapitools/typescript-nestjs-petstore';
@Module({
imports: [],
declarations: [ AppComponent ],
providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
```
#### Using @nestjs/cli
First extend your `src/environments/*.ts` files by adding the corresponding base path:
```
export const environment = {
production: false,
API_BASE_PATH: 'http://127.0.0.1:8080'
};
```
In the src/app/app.module.ts:
```
import { BASE_PATH } from '@openapitools/typescript-nestjs-petstore';
import { environment } from '../environments/environment';
@Module({
declarations: [
AppComponent
],
imports: [ ],
providers: [
{
provide: 'BASE_PATH',
useValue: environment.API_BASE_PATH
}
]
})
export class AppModule { }
```

View File

@ -0,0 +1,28 @@
import { DynamicModule, HttpService, HttpModule, Module, Global } from '@nestjs/common';
import { Configuration } from './configuration';
import { BASE_PATH } from './variables';
import { PetService } from './api/pet.service';
import { StoreService } from './api/store.service';
import { UserService } from './api/user.service';
@Global
@Module({
imports: [ HttpModule ],
exports: [
PetServiceStoreServiceUserService
],
providers: [
PetServiceStoreServiceUserService
]
})
export class ApiModule {
public static forRoot(configurationFactory: () => Configuration): DynamicModule {
return {
module: ApiModule,
providers: [ { provide: Configuration, useFactory: configurationFactory } ]
};
}
constructor( httpService: HttpService) { }
}

View File

@ -0,0 +1,7 @@
export * from './pet.service';
import { PetService } from './pet.service';
export * from './store.service';
import { StoreService } from './store.service';
export * from './user.service';
import { UserService } from './user.service';
export const APIS = [PetService, StoreService, UserService];

View File

@ -0,0 +1,478 @@
/**
* OpenAPI Petstore
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/* tslint:disable:no-unused-variable member-ordering */
import { HttpService, Inject, Injectable } from '@nestjs/common';
import { AxiosResponse } from 'axios';
import { Observable } from 'rxjs';
import { ApiResponse } from '../model/apiResponse';
import { Pet } from '../model/pet';
import { Configuration } from '../configuration';
import { COLLECTION_FORMATS } from '../variables';
@Injectable()
export class PetService {
protected basePath = 'http://petstore.swagger.io/v2';
public defaultHeaders = new Map()
public configuration = new Configuration();
constructor(protected httpClient: HttpService, configuration: Configuration) {
this.configuration = configuration;
this.basePath = basePath || configuration.basePath || this.basePath;
}
/**
* @param consumes string[] mime-types
* @return true: consumes contains 'multipart/form-data', false: otherwise
*/
private canConsumeForm(consumes: string[]): boolean {
const form = 'multipart/form-data';
return consumes.includes(form);
}
/**
* Add a new pet to the store
*
* @param pet Pet object that needs to be added to the store
* @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.
*/
public addPet(pet: Pet, ): Observable<AxiosResponse<Pet>>;
public addPet(pet: Pet, ): Observable<any> {
if (pet === null || pet === undefined) {
throw new Error('Required parameter pet was null or undefined when calling addPet.');
}
let headers = this.defaultHeaders;
// authentication (petstore_auth) required
if (this.configuration.accessToken) {
const accessToken = typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: this.configuration.accessToken;
headers['Authorization'] = 'Bearer ' + accessToken;
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/xml'
'application/json'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
'application/json'
'application/xml'
];
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected != undefined) {
headers['Content-Type'] = httpContentTypeSelected;
}
return this.httpClient.post<Pet>(`${this.basePath}/pet`,
pet,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Deletes a pet
*
* @param petId Pet id to delete
* @param apiKey
* @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.
*/
public deletePet(petId: number, apiKey?: string, ): Observable<AxiosResponse<any>>;
public deletePet(petId: number, apiKey?: string, ): Observable<any> {
if (petId === null || petId === undefined) {
throw new Error('Required parameter petId was null or undefined when calling deletePet.');
}
let headers = this.defaultHeaders;
if (apiKey !== undefined && apiKey !== null) {
headers['api_key'] String(apiKey);
}
// authentication (petstore_auth) required
if (this.configuration.accessToken) {
const accessToken = typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: this.configuration.accessToken;
headers['Authorization'] = 'Bearer ' + accessToken;
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.delete<any>(`${this.basePath}/pet/${encodeURIComponent(String(petId))}`,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Finds Pets by status
* Multiple status values can be provided with comma separated strings
* @param status Status values that need to be considered for filter
* @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.
*/
public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, ): Observable<AxiosResponse<Array<Pet>>>;
public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, ): Observable<any> {
if (status === null || status === undefined) {
throw new Error('Required parameter status was null or undefined when calling findPetsByStatus.');
}
let queryParameters = {};
if (status !== undefined && status !== null) {
queryParameters['status'] <any>status;
}
let headers = this.defaultHeaders;
// authentication (petstore_auth) required
if (this.configuration.accessToken) {
const accessToken = typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: this.configuration.accessToken;
headers['Authorization'] = 'Bearer ' + accessToken;
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/xml'
'application/json'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.get<Array<Pet>>(`${this.basePath}/pet/findByStatus`,
{
params: queryParameters,
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Finds Pets by tags
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
* @param tags Tags to filter by
* @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.
*/
public findPetsByTags(tags: Array<string>, ): Observable<AxiosResponse<Array<Pet>>>;
public findPetsByTags(tags: Array<string>, ): Observable<any> {
if (tags === null || tags === undefined) {
throw new Error('Required parameter tags was null or undefined when calling findPetsByTags.');
}
let queryParameters = {};
if (tags !== undefined && tags !== null) {
queryParameters['tags'] <any>tags;
}
let headers = this.defaultHeaders;
// authentication (petstore_auth) required
if (this.configuration.accessToken) {
const accessToken = typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: this.configuration.accessToken;
headers['Authorization'] = 'Bearer ' + accessToken;
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/xml'
'application/json'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.get<Array<Pet>>(`${this.basePath}/pet/findByTags`,
{
params: queryParameters,
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Find pet by ID
* Returns a single pet
* @param petId ID of pet to return
* @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.
*/
public getPetById(petId: number, ): Observable<AxiosResponse<Pet>>;
public getPetById(petId: number, ): Observable<any> {
if (petId === null || petId === undefined) {
throw new Error('Required parameter petId was null or undefined when calling getPetById.');
}
let headers = this.defaultHeaders;
// authentication (api_key) required
if (this.configuration.apiKeys["api_key"]) {
headers['api_key'] = this.configuration.apiKeys["api_key"];
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/xml'
'application/json'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.get<Pet>(`${this.basePath}/pet/${encodeURIComponent(String(petId))}`,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Update an existing pet
*
* @param pet Pet object that needs to be added to the store
* @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.
*/
public updatePet(pet: Pet, ): Observable<AxiosResponse<Pet>>;
public updatePet(pet: Pet, ): Observable<any> {
if (pet === null || pet === undefined) {
throw new Error('Required parameter pet was null or undefined when calling updatePet.');
}
let headers = this.defaultHeaders;
// authentication (petstore_auth) required
if (this.configuration.accessToken) {
const accessToken = typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: this.configuration.accessToken;
headers['Authorization'] = 'Bearer ' + accessToken;
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/xml'
'application/json'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
'application/json'
'application/xml'
];
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected != undefined) {
headers['Content-Type'] = httpContentTypeSelected;
}
return this.httpClient.put<Pet>(`${this.basePath}/pet`,
pet,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Updates a pet in the store with form data
*
* @param petId ID of pet that needs to be updated
* @param name Updated name of the pet
* @param status Updated status of the pet
* @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.
*/
public updatePetWithForm(petId: number, name?: string, status?: string, ): Observable<AxiosResponse<any>>;
public updatePetWithForm(petId: number, name?: string, status?: string, ): Observable<any> {
if (petId === null || petId === undefined) {
throw new Error('Required parameter petId was null or undefined when calling updatePetWithForm.');
}
let headers = this.defaultHeaders;
// authentication (petstore_auth) required
if (this.configuration.accessToken) {
const accessToken = typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: this.configuration.accessToken;
headers['Authorization'] = 'Bearer ' + accessToken;
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
'application/x-www-form-urlencoded'
];
const canConsumeForm = this.canConsumeForm(consumes);
let formParams: { append(param: string, value: any): void; };
let useForm = false;
let convertFormParamsToString = false;
if (useForm) {
formParams = new FormData();
} else {
// formParams = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
}
if (name !== undefined) {
formParams.append('name', <any>name);
}
if (status !== undefined) {
formParams.append('status', <any>status);
}
return this.httpClient.post<any>(`${this.basePath}/pet/${encodeURIComponent(String(petId))}`,
convertFormParamsToString ? formParams.toString() : formParams,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* uploads an image
*
* @param petId ID of pet to update
* @param additionalMetadata Additional data to pass to server
* @param file file to upload
* @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.
*/
public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, ): Observable<AxiosResponse<ApiResponse>>;
public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, ): Observable<any> {
if (petId === null || petId === undefined) {
throw new Error('Required parameter petId was null or undefined when calling uploadFile.');
}
let headers = this.defaultHeaders;
// authentication (petstore_auth) required
if (this.configuration.accessToken) {
const accessToken = typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: this.configuration.accessToken;
headers['Authorization'] = 'Bearer ' + accessToken;
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/json'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
'multipart/form-data'
];
const canConsumeForm = this.canConsumeForm(consumes);
let formParams: { append(param: string, value: any): void; };
let useForm = false;
let convertFormParamsToString = false;
// 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
useForm = canConsumeForm;
if (useForm) {
formParams = new FormData();
} else {
// formParams = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
}
if (additionalMetadata !== undefined) {
formParams.append('additionalMetadata', <any>additionalMetadata);
}
if (file !== undefined) {
formParams.append('file', <any>file);
}
return this.httpClient.post<ApiResponse>(`${this.basePath}/pet/${encodeURIComponent(String(petId))}/uploadImage`,
convertFormParamsToString ? formParams.toString() : formParams,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
}

View File

@ -0,0 +1,194 @@
/**
* OpenAPI Petstore
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/* tslint:disable:no-unused-variable member-ordering */
import { HttpService, Inject, Injectable } from '@nestjs/common';
import { AxiosResponse } from 'axios';
import { Observable } from 'rxjs';
import { Order } from '../model/order';
import { Configuration } from '../configuration';
import { COLLECTION_FORMATS } from '../variables';
@Injectable()
export class StoreService {
protected basePath = 'http://petstore.swagger.io/v2';
public defaultHeaders = new Map()
public configuration = new Configuration();
constructor(protected httpClient: HttpService, configuration: Configuration) {
this.configuration = configuration;
this.basePath = basePath || configuration.basePath || this.basePath;
}
/**
* @param consumes string[] mime-types
* @return true: consumes contains 'multipart/form-data', false: otherwise
*/
private canConsumeForm(consumes: string[]): boolean {
const form = 'multipart/form-data';
return consumes.includes(form);
}
/**
* Delete purchase order by ID
* For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
* @param orderId ID of the order that needs to be deleted
* @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.
*/
public deleteOrder(orderId: string, ): Observable<AxiosResponse<any>>;
public deleteOrder(orderId: string, ): Observable<any> {
if (orderId === null || orderId === undefined) {
throw new Error('Required parameter orderId was null or undefined when calling deleteOrder.');
}
let headers = this.defaultHeaders;
// to determine the Accept header
let httpHeaderAccepts: string[] = [
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.delete<any>(`${this.basePath}/store/order/${encodeURIComponent(String(orderId))}`,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Returns pet inventories by status
* Returns a map of status codes to quantities
* @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.
*/
public getInventory(): Observable<AxiosResponse<{ [key: string]: number; }>>;
public getInventory(): Observable<any> {
let headers = this.defaultHeaders;
// authentication (api_key) required
if (this.configuration.apiKeys["api_key"]) {
headers['api_key'] = this.configuration.apiKeys["api_key"];
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/json'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.get<{ [key: string]: number; }>(`${this.basePath}/store/inventory`,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Find purchase order by ID
* For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generated exceptions
* @param orderId ID of pet that needs to be fetched
* @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.
*/
public getOrderById(orderId: number, ): Observable<AxiosResponse<Order>>;
public getOrderById(orderId: number, ): Observable<any> {
if (orderId === null || orderId === undefined) {
throw new Error('Required parameter orderId was null or undefined when calling getOrderById.');
}
let headers = this.defaultHeaders;
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/xml'
'application/json'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.get<Order>(`${this.basePath}/store/order/${encodeURIComponent(String(orderId))}`,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Place an order for a pet
*
* @param order order placed for purchasing the pet
* @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.
*/
public placeOrder(order: Order, ): Observable<AxiosResponse<Order>>;
public placeOrder(order: Order, ): Observable<any> {
if (order === null || order === undefined) {
throw new Error('Required parameter order was null or undefined when calling placeOrder.');
}
let headers = this.defaultHeaders;
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/xml'
'application/json'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
'application/json'
];
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected != undefined) {
headers['Content-Type'] = httpContentTypeSelected;
}
return this.httpClient.post<Order>(`${this.basePath}/store/order`,
order,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
}

View File

@ -0,0 +1,395 @@
/**
* OpenAPI Petstore
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/* tslint:disable:no-unused-variable member-ordering */
import { HttpService, Inject, Injectable } from '@nestjs/common';
import { AxiosResponse } from 'axios';
import { Observable } from 'rxjs';
import { User } from '../model/user';
import { Configuration } from '../configuration';
import { COLLECTION_FORMATS } from '../variables';
@Injectable()
export class UserService {
protected basePath = 'http://petstore.swagger.io/v2';
public defaultHeaders = new Map()
public configuration = new Configuration();
constructor(protected httpClient: HttpService, configuration: Configuration) {
this.configuration = configuration;
this.basePath = basePath || configuration.basePath || this.basePath;
}
/**
* @param consumes string[] mime-types
* @return true: consumes contains 'multipart/form-data', false: otherwise
*/
private canConsumeForm(consumes: string[]): boolean {
const form = 'multipart/form-data';
return consumes.includes(form);
}
/**
* Create user
* This can only be done by the logged in user.
* @param user Created user object
* @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.
*/
public createUser(user: User, ): Observable<AxiosResponse<any>>;
public createUser(user: User, ): Observable<any> {
if (user === null || user === undefined) {
throw new Error('Required parameter user was null or undefined when calling createUser.');
}
let headers = this.defaultHeaders;
// authentication (api_key) required
if (this.configuration.apiKeys["api_key"]) {
headers['api_key'] = this.configuration.apiKeys["api_key"];
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
'application/json'
];
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected != undefined) {
headers['Content-Type'] = httpContentTypeSelected;
}
return this.httpClient.post<any>(`${this.basePath}/user`,
user,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Creates list of users with given input array
*
* @param user List of user object
* @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.
*/
public createUsersWithArrayInput(user: Array<User>, ): Observable<AxiosResponse<any>>;
public createUsersWithArrayInput(user: Array<User>, ): Observable<any> {
if (user === null || user === undefined) {
throw new Error('Required parameter user was null or undefined when calling createUsersWithArrayInput.');
}
let headers = this.defaultHeaders;
// authentication (api_key) required
if (this.configuration.apiKeys["api_key"]) {
headers['api_key'] = this.configuration.apiKeys["api_key"];
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
'application/json'
];
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected != undefined) {
headers['Content-Type'] = httpContentTypeSelected;
}
return this.httpClient.post<any>(`${this.basePath}/user/createWithArray`,
user,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Creates list of users with given input array
*
* @param user List of user object
* @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.
*/
public createUsersWithListInput(user: Array<User>, ): Observable<AxiosResponse<any>>;
public createUsersWithListInput(user: Array<User>, ): Observable<any> {
if (user === null || user === undefined) {
throw new Error('Required parameter user was null or undefined when calling createUsersWithListInput.');
}
let headers = this.defaultHeaders;
// authentication (api_key) required
if (this.configuration.apiKeys["api_key"]) {
headers['api_key'] = this.configuration.apiKeys["api_key"];
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
'application/json'
];
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected != undefined) {
headers['Content-Type'] = httpContentTypeSelected;
}
return this.httpClient.post<any>(`${this.basePath}/user/createWithList`,
user,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Delete user
* This can only be done by the logged in user.
* @param username The name that needs to be deleted
* @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.
*/
public deleteUser(username: string, ): Observable<AxiosResponse<any>>;
public deleteUser(username: string, ): Observable<any> {
if (username === null || username === undefined) {
throw new Error('Required parameter username was null or undefined when calling deleteUser.');
}
let headers = this.defaultHeaders;
// authentication (api_key) required
if (this.configuration.apiKeys["api_key"]) {
headers['api_key'] = this.configuration.apiKeys["api_key"];
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.delete<any>(`${this.basePath}/user/${encodeURIComponent(String(username))}`,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Get user by user name
*
* @param username The name that needs to be fetched. Use user1 for testing.
* @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.
*/
public getUserByName(username: string, ): Observable<AxiosResponse<User>>;
public getUserByName(username: string, ): Observable<any> {
if (username === null || username === undefined) {
throw new Error('Required parameter username was null or undefined when calling getUserByName.');
}
let headers = this.defaultHeaders;
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/xml'
'application/json'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.get<User>(`${this.basePath}/user/${encodeURIComponent(String(username))}`,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Logs user into the system
*
* @param username The user name for login
* @param password The password for login in clear text
* @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.
*/
public loginUser(username: string, password: string, ): Observable<AxiosResponse<string>>;
public loginUser(username: string, password: string, ): Observable<any> {
if (username === null || username === undefined) {
throw new Error('Required parameter username was null or undefined when calling loginUser.');
}
if (password === null || password === undefined) {
throw new Error('Required parameter password was null or undefined when calling loginUser.');
}
let queryParameters = {};
if (username !== undefined && username !== null) {
queryParameters['username'] <any>username;
}
if (password !== undefined && password !== null) {
queryParameters['password'] <any>password;
}
let headers = this.defaultHeaders;
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/xml'
'application/json'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.get<string>(`${this.basePath}/user/login`,
{
params: queryParameters,
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Logs out current logged in user session
*
* @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.
*/
public logoutUser(): Observable<AxiosResponse<any>>;
public logoutUser(): Observable<any> {
let headers = this.defaultHeaders;
// authentication (api_key) required
if (this.configuration.apiKeys["api_key"]) {
headers['api_key'] = this.configuration.apiKeys["api_key"];
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.get<any>(`${this.basePath}/user/logout`,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
/**
* Updated user
* This can only be done by the logged in user.
* @param username name that need to be deleted
* @param user Updated user object
* @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.
*/
public updateUser(username: string, user: User, ): Observable<AxiosResponse<any>>;
public updateUser(username: string, user: User, ): Observable<any> {
if (username === null || username === undefined) {
throw new Error('Required parameter username was null or undefined when calling updateUser.');
}
if (user === null || user === undefined) {
throw new Error('Required parameter user was null or undefined when calling updateUser.');
}
let headers = this.defaultHeaders;
// authentication (api_key) required
if (this.configuration.apiKeys["api_key"]) {
headers['api_key'] = this.configuration.apiKeys["api_key"];
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers['Accept'] = httpHeaderAcceptSelected;
}
// to determine the Content-Type header
const consumes: string[] = [
'application/json'
];
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected != undefined) {
headers['Content-Type'] = httpContentTypeSelected;
}
return this.httpClient.put<any>(`${this.basePath}/user/${encodeURIComponent(String(username))}`,
user,
{
withCredentials: this.configuration.withCredentials,
headers: headers
}
);
}
}

View File

@ -0,0 +1,79 @@
export interface ConfigurationParameters {
apiKeys?: {[ key: string ]: string};
username?: string;
password?: string;
accessToken?: string | (() => string);
basePath?: string;
withCredentials?: boolean;
}
export class Configuration {
apiKeys?: {[ key: string ]: string};
username?: string;
password?: string;
accessToken?: string | (() => string);
basePath?: string;
withCredentials?: boolean;
constructor(configurationParameters: ConfigurationParameters = {}) {
this.apiKeys = configurationParameters.apiKeys;
this.username = configurationParameters.username;
this.password = configurationParameters.password;
this.accessToken = configurationParameters.accessToken;
this.basePath = configurationParameters.basePath;
this.withCredentials = configurationParameters.withCredentials;
}
/**
* Select the correct content-type to use for a request.
* Uses {@link Configuration#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;
}
let type = contentTypes.find(x => this.isJsonMime(x));
if (type === undefined) {
return contentTypes[0];
}
return type;
}
/**
* Select the correct accept content-type to use for a request.
* Uses {@link Configuration#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;
}
let type = accepts.find(x => 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');
}
}

View File

@ -0,0 +1,58 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" "gitlab.com"
git_user_id=$1
git_repo_id=$2
release_note=$3
git_host=$4
if [ "$git_host" = "" ]; then
git_host="github.com"
echo "[INFO] No command line input provided. Set \$git_host to $git_host"
fi
if [ "$git_user_id" = "" ]; then
git_user_id="GIT_USER_ID"
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
fi
if [ "$git_repo_id" = "" ]; then
git_repo_id="GIT_REPO_ID"
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
fi
if [ "$release_note" = "" ]; then
release_note="Minor update"
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

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

View File

@ -0,0 +1,22 @@
/**
* OpenAPI Petstore
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
* Describes the result of uploading an image resource
*/
export interface ApiResponse {
code?: number;
type?: string;
message?: string;
}

View File

@ -0,0 +1,21 @@
/**
* OpenAPI Petstore
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
* A category for a pet
*/
export interface Category {
id?: number;
name?: string;
}

View File

@ -0,0 +1,6 @@
export * from './apiResponse';
export * from './category';
export * from './order';
export * from './pet';
export * from './tag';
export * from './user';

View File

@ -0,0 +1,37 @@
/**
* OpenAPI Petstore
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
* An order for a pets from the pet store
*/
export interface Order {
id?: number;
petId?: number;
quantity?: number;
shipDate?: string;
/**
* Order Status
*/
status?: Order.StatusEnum;
complete?: boolean;
}
export namespace Order {
export type StatusEnum = 'placed' | 'approved' | 'delivered';
export const StatusEnum = {
Placed: 'placed' as StatusEnum,
Approved: 'approved' as StatusEnum,
Delivered: 'delivered' as StatusEnum
};
}

View File

@ -0,0 +1,39 @@
/**
* OpenAPI Petstore
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { Category } from './category';
import { Tag } from './tag';
/**
* A pet for sale in the pet store
*/
export interface Pet {
id?: number;
category?: Category;
name: string;
photoUrls: Array<string>;
tags?: Array<Tag>;
/**
* pet status in the store
*/
status?: Pet.StatusEnum;
}
export namespace Pet {
export type StatusEnum = 'available' | 'pending' | 'sold';
export const StatusEnum = {
Available: 'available' as StatusEnum,
Pending: 'pending' as StatusEnum,
Sold: 'sold' as StatusEnum
};
}

View File

@ -0,0 +1,21 @@
/**
* OpenAPI Petstore
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
* A tag for a pet
*/
export interface Tag {
id?: number;
name?: string;
}

View File

@ -0,0 +1,30 @@
/**
* OpenAPI Petstore
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
* A User who is purchasing from the pet store
*/
export interface User {
id?: number;
username?: string;
firstName?: string;
lastName?: string;
email?: string;
password?: string;
phone?: string;
/**
* User Status
*/
userStatus?: number;
}

View File

@ -0,0 +1,69 @@
{
"name": "@openapitools/typescript-nestjs-petstore",
"version": "1.0.0",
"description": "REST client for @openapitools/typescript-nestjs-petstore",
"author": "OpenAPI Generator Contributors",
"keywords": [
"swagger-client"
],
"license": "Unlicense",
"scripts": {
"build": "tsc -p tsconfig.build.json",
"build:clean": "rm -rf dist/ 2> /dev/null && tsc -p tsconfig.build.json",
"format": "prettier --write \"src/**/*.ts\"",
"start": "ts-node -r tsconfig-paths/register src/main.ts",
"start:dev": "concurrently --handle-input \"wait-on dist/main.js && nodemon\" \"tsc -w -p tsconfig.build.json\" ",
"start:debug": "nodemon --config nodemon-debug.json",
"prestart:prod": "rimraf dist && npm run build",
"start:prod": "node dist/main.js",
"lint": "tslint -p tsconfig.json -c tslint.json",
"lint:fix": "tslint -p tsconfig.json -c tslint.json --fix --force",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^6.0.0",
"@nestjs/core": "^6.0.0",
"@nestjs/platform-express": "^6.0.0",
"reflect-metadata": "^0.1.13",
"rimraf": "^2.6.3",
"rxjs": "^6.5.2"
},
"devDependencies": {
"@nestjs/testing": "~6.0.0",
"@types/express": "^4.16.0",
"@types/jest": "^24.0.15",
"@types/node": "^12.6.1",
"@types/supertest": "^2.0.8",
"concurrently": "^4.1.1",
"nodemon": "^1.19.1",
"prettier": "^1.18.2",
"supertest": "^4.0.2",
"ts-jest": "24.0.2",
"ts-node": "8.3.0",
"tsconfig-paths": "3.8.0",
"tslint": "5.18.0",
"typescript": "3.5.3",
"wait-on": "^3.2.0"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "../coverage",
"testEnvironment": "node"
},
"publishConfig": {
"registry": "https://skimdb.npmjs.com/registry"
}
}

View File

@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"exclude": [
"node_modules",
"test",
"dist",
"**/*spec.ts"
]
}

View File

@ -0,0 +1,22 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true
},
"exclude": [
"node_modules",
"dist"
],
"filesGlob": [
"./model/*.ts",
"./api/*.ts"
]
}

View File

@ -0,0 +1,18 @@
{
"defaultSeverity": "error",
"extends": ["tslint:recommended"],
"jsRules": {
"no-unused-expression": true
},
"rules": {
"quotemark": [true, "single"],
"member-access": [false],
"ordered-imports": [false],
"max-line-length": [true, 150],
"member-ordering": [false],
"interface-name": [false],
"arrow-parens": false,
"object-literal-sort-keys": false
},
"rulesDirectory": []
}

View File

@ -0,0 +1,7 @@
export const COLLECTION_FORMATS = {
'csv': ',',
'tsv': ' ',
'ssv': ' ',
'pipes': '|'
}