From b9a6be0cba2fc21913bafba60a69e7815a336b98 Mon Sep 17 00:00:00 2001 From: Christoph Linder Date: Wed, 24 Aug 2022 09:35:40 +0200 Subject: [PATCH] fixes #13131: support matrix parameters and other parameter styles in typescript-angular (#13132) * fix TypescriptAngularPetstoreIntegrationTest (since this has been abandoned for a long time: just copy the generated code the the "expected" directory) * fix TypescriptAngularArrayAndObjectIntegrationTest (since this has been abandoned for a long time: just copy the generated code the the "expected" directory) * fix TypescriptAngularAdditionalPropertiesIntegrationTest (since this has been abandoned for a long time: just copy the generated code the the "expected" directory) * fixes #13131: add custom path parameter expansion to typescript-angular * fixes #13131: add example for typescript-angular: paramExpansionStrategy=custom * fixes #13131: document usage of paramExpansionStrategy=custom in README.mustache * fixes #13131: fix unit tests and sample url for http-param-expander package * fixes #13131: update samples * fixes #13131: drop new cli parameter, handle encoding in template only * fixes #13131: add TestNG groups to all Typescript tests * fixes #13131: old angular/typescript does not understand type imports * Apply suggestions from code review Co-authored-by: Esteban Gehring * fixes #13131: implement backwards-compatible behavior for format: 'date-time' * fixes #13131: update typescript-angular integrationtests * fixes #13131: review fixes + lots of documentation * fixes #13131: update integrationtests * fixes #13131: update docs/examples * fixes #13131: update integrationtests * fixes #13131: unify enums to union-types to make the api feel mora angular-ish * fixes #13131: update examples * fixes #13131: update docs/examples after merge of master Co-authored-by: Christoph Linder Co-authored-by: Esteban Gehring --- docs/generators/typescript-angular.md | 2 +- .../AbstractTypeScriptClientCodegen.java | 171 +++ .../TypeScriptAngularClientCodegen.java | 42 +- .../typescript-angular/README.mustache | 23 + .../typescript-angular/api.service.mustache | 3 +- .../typescript-angular/configuration.mustache | 45 + .../typescript-angular/index.mustache | 3 +- .../typescript-angular/param.mustache | 69 ++ .../codegen/testutils/AssertFile.java | 9 +- .../typescript/SharedTypeScriptTest.java | 5 +- .../TypeScriptClientCodegenTest.java | 2 +- .../typescript/TypeScriptClientModelTest.java | 2 +- .../codegen/typescript/TypeScriptGroups.java | 28 + .../TypeScriptAureliaClientOptionsTest.java | 3 + .../TypeScriptAxiosClientCodegenTest.java | 2 + .../TypeScriptFetchClientCodegenTest.java | 7 +- .../TypeScriptFetchClientOptionsTest.java | 3 + .../fetch/TypeScriptFetchModelTest.java | 2 + .../TypeScriptAngularClientCodegenTest.java | 2 + .../TypeScriptAngularClientOptionsTest.java | 3 + .../TypeScriptAngularModelTest.java | 2 + ...arAdditionalPropertiesIntegrationTest.java | 18 + .../TypescriptAngularApiVersionTest.java | 2 + ...tAngularArrayAndObjectIntegrationTest.java | 18 + ...arParamsStrategyCustomIntegrationTest.java | 66 ++ ...escriptAngularPetstoreIntegrationTest.java | 18 + .../TypeScriptNestjsClientCodegenTest.java | 2 + .../TypeScriptNestjsClientOptionsTest.java | 3 + .../TypeScriptNestjsModelTest.java | 2 + ...jsAdditionalPropertiesIntegrationTest.java | 3 + .../TypescriptNestjsApiVersionTest.java | 2 + ...ptNestjsArrayAndObjectIntegrationTest.java | 3 + ...pescriptNestjsPetstoreIntegrationTest.java | 3 + .../TypeScriptNodeClientCodegenTest.java | 2 + .../TypeScriptNodeClientOptionsTest.java | 3 + .../TypeScriptNodeModelTest.java | 4 +- .../TypescriptNodeES5IntegrationTest.java | 3 + .../TypescriptNodeEnumIntegrationTest.java | 3 + .../additional-properties-expected/.gitignore | 1 + .../.openapi-generator-ignore | 23 - .../additional-properties-expected/LICENSE | 201 ---- .../additional-properties-expected/README.md | 202 +++- .../api.module.ts | 24 +- .../additional-properties-expected/api/api.ts | 2 + .../api/user.service.ts | 310 +++-- .../configuration.ts | 176 ++- .../additional-properties-expected/encoder.ts | 20 + .../git_push.sh | 17 +- .../additional-properties-expected/index.ts | 3 +- .../model/user.ts | 29 +- .../ng-package.json | 6 + .../package.json | 50 +- .../additional-properties-expected/param.ts | 69 ++ .../rxjs-operators.ts | 11 - .../tsconfig.json | 52 +- .../typings.json | 5 - .../variables.ts | 10 +- .../array-and-object-expected/.gitignore | 1 + .../.openapi-generator-ignore | 23 - .../array-and-object-expected/LICENSE | 201 ---- .../array-and-object-expected/README.md | 202 +++- .../array-and-object-expected/api.module.ts | 24 +- .../array-and-object-expected/api/api.ts | 2 + .../api/project.service.ts | 657 ++++++----- .../configuration.ts | 176 ++- .../array-and-object-expected/encoder.ts | 20 + .../array-and-object-expected/git_push.sh | 17 +- .../array-and-object-expected/index.ts | 3 +- .../model/projectEntity.ts | 52 +- .../model/projectEntityLocation.ts | 26 +- .../model/projectList.ts | 25 +- .../array-and-object-expected/ng-package.json | 6 + .../array-and-object-expected/package.json | 50 +- .../array-and-object-expected/param.ts | 69 ++ .../rxjs-operators.ts | 11 - .../array-and-object-expected/tsconfig.json | 52 +- .../array-and-object-expected/typings.json | 5 - .../array-and-object-expected/variables.ts | 10 +- .../custom-path-params-expected/.gitignore | 4 + .../custom-path-params-expected/README.md | 226 ++++ .../custom-path-params-expected/api.module.ts | 31 + .../custom-path-params-expected/api/api.ts | 3 + .../api/matrixParams.service.ts | 310 +++++ .../configuration.ts | 166 +++ .../custom-path-params-expected/encoder.ts | 20 + .../custom-path-params-expected/git_push.sh | 57 + .../custom-path-params-expected/index.ts | 6 + .../model/complexParams.ts | 18 + .../model/models.ts | 1 + .../ng-package.json | 6 + .../custom-path-params-expected/package.json | 34 + .../custom-path-params-expected/param.ts | 69 ++ .../custom-path-params-expected/tsconfig.json | 28 + .../custom-path-params-expected/variables.ts | 9 + .../typescript/custom-path-params-spec.json | 129 ++ .../typescript/petstore-expected/.gitignore | 1 + .../.openapi-generator-ignore | 23 - .../typescript/petstore-expected/LICENSE | 201 ---- .../typescript/petstore-expected/README.md | 202 +++- .../petstore-expected/api.module.ts | 24 +- .../typescript/petstore-expected/api/api.ts | 4 + .../petstore-expected/api/pet.service.ts | 1038 +++++++++-------- .../petstore-expected/api/store.service.ts | 515 ++++---- .../petstore-expected/api/user.service.ts | 919 ++++++++------- .../petstore-expected/configuration.ts | 196 +++- .../typescript/petstore-expected/encoder.ts | 20 + .../typescript/petstore-expected/git_push.sh | 17 +- .../typescript/petstore-expected/index.ts | 3 +- .../petstore-expected/model/apiResponse.ts | 31 +- .../petstore-expected/model/category.ts | 30 +- .../petstore-expected/model/order.ts | 48 +- .../typescript/petstore-expected/model/pet.ts | 46 +- .../typescript/petstore-expected/model/tag.ts | 30 +- .../petstore-expected/model/user.ts | 36 +- .../petstore-expected/ng-package.json | 6 + .../typescript/petstore-expected/package.json | 50 +- .../typescript/petstore-expected/param.ts | 69 ++ .../petstore-expected/rxjs-operators.ts | 11 - .../petstore-expected/tsconfig.json | 52 +- .../typescript/petstore-expected/typings.json | 5 - .../typescript/petstore-expected/variables.ts | 10 +- .../builds/default/.openapi-generator/FILES | 1 + .../builds/default/README.md | 23 + .../builds/default/api/default.service.ts | 6 +- .../builds/default/configuration.ts | 45 + .../builds/default/index.ts | 3 +- .../builds/default/param.ts | 69 ++ .../builds/default/.openapi-generator/FILES | 1 + .../builds/default/README.md | 23 + .../builds/default/api/pet.service.ts | 24 +- .../builds/default/api/store.service.ts | 12 +- .../builds/default/api/user.service.ts | 24 +- .../builds/default/configuration.ts | 45 + .../builds/default/index.ts | 3 +- .../builds/default/param.ts | 69 ++ .../builds/default/.openapi-generator/FILES | 1 + .../builds/default/README.md | 23 + .../builds/default/api/pet.service.ts | 24 +- .../builds/default/api/store.service.ts | 12 +- .../builds/default/api/user.service.ts | 24 +- .../builds/default/configuration.ts | 45 + .../builds/default/index.ts | 3 +- .../builds/default/param.ts | 69 ++ .../builds/with-npm/.openapi-generator/FILES | 1 + .../builds/with-npm/README.md | 23 + .../builds/with-npm/api/pet.service.ts | 24 +- .../builds/with-npm/api/store.service.ts | 12 +- .../builds/with-npm/api/user.service.ts | 24 +- .../builds/with-npm/configuration.ts | 45 + .../builds/with-npm/index.ts | 3 +- .../builds/with-npm/param.ts | 69 ++ .../builds/default/.openapi-generator/FILES | 1 + .../builds/default/README.md | 23 + .../builds/default/api/default.service.ts | 6 +- .../builds/default/configuration.ts | 45 + .../builds/default/index.ts | 3 +- .../builds/default/param.ts | 69 ++ .../builds/default/.openapi-generator/FILES | 1 + .../builds/default/README.md | 23 + .../builds/default/api/pet.service.ts | 24 +- .../builds/default/api/store.service.ts | 12 +- .../builds/default/api/user.service.ts | 24 +- .../builds/default/configuration.ts | 45 + .../builds/default/index.ts | 3 +- .../builds/default/param.ts | 69 ++ .../builds/default/.openapi-generator/FILES | 1 + .../builds/default/README.md | 23 + .../builds/default/api/pet.service.ts | 24 +- .../builds/default/api/store.service.ts | 12 +- .../builds/default/api/user.service.ts | 24 +- .../builds/default/configuration.ts | 45 + .../builds/default/index.ts | 3 +- .../builds/default/param.ts | 69 ++ .../builds/with-npm/.openapi-generator/FILES | 1 + .../builds/with-npm/README.md | 23 + .../builds/with-npm/api/pet.service.ts | 24 +- .../builds/with-npm/api/store.service.ts | 12 +- .../builds/with-npm/api/user.service.ts | 24 +- .../builds/with-npm/configuration.ts | 45 + .../builds/with-npm/index.ts | 3 +- .../builds/with-npm/param.ts | 69 ++ .../builds/default/.openapi-generator/FILES | 1 + .../builds/default/README.md | 23 + .../builds/default/api/pet.service.ts | 24 +- .../builds/default/api/store.service.ts | 12 +- .../builds/default/api/user.service.ts | 24 +- .../builds/default/configuration.ts | 45 + .../builds/default/index.ts | 3 +- .../builds/default/param.ts | 69 ++ 189 files changed, 6797 insertions(+), 3034 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/typescript-angular/param.mustache create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptGroups.java create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularParamsStrategyCustomIntegrationTest.java delete mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/.openapi-generator-ignore delete mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/LICENSE create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/encoder.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/ng-package.json create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/param.ts delete mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/rxjs-operators.ts delete mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/typings.json delete mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/.openapi-generator-ignore delete mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/LICENSE create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/encoder.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/ng-package.json create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/param.ts delete mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/rxjs-operators.ts delete mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/typings.json create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/.gitignore create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/README.md create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api.module.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api/api.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api/matrixParams.service.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/configuration.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/encoder.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/git_push.sh create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/index.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/model/complexParams.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/model/models.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/ng-package.json create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/package.json create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/param.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/tsconfig.json create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/variables.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-spec.json delete mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/.openapi-generator-ignore delete mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/LICENSE create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/encoder.ts create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/ng-package.json create mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/param.ts delete mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/rxjs-operators.ts delete mode 100644 modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/typings.json create mode 100644 samples/client/petstore/typescript-angular-v12-oneOf/builds/default/param.ts create mode 100644 samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/param.ts create mode 100644 samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/param.ts create mode 100644 samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/param.ts create mode 100644 samples/client/petstore/typescript-angular-v13-oneOf/builds/default/param.ts create mode 100644 samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/param.ts create mode 100644 samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/param.ts create mode 100644 samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/param.ts create mode 100644 samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/param.ts diff --git a/docs/generators/typescript-angular.md b/docs/generators/typescript-angular.md index 9192d4c1a1f..7fde34c39a3 100644 --- a/docs/generators/typescript-angular.md +++ b/docs/generators/typescript-angular.md @@ -232,7 +232,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |XMLStructureDefinitions|✗|OAS2,OAS3 |MultiServer|✗|OAS3 |ParameterizedServer|✗|OAS3 -|ParameterStyling|✗|OAS3 +|ParameterStyling|✓|OAS3 |Callbacks|✗|OAS3 |LinkObjects|✗|OAS3 diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java index 5d223ca1aed..4cac98e9ffe 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java @@ -24,6 +24,7 @@ import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.Parameter; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; +import org.checkerframework.checker.nullness.qual.Nullable; import org.openapitools.codegen.CodegenConstants.ENUM_PROPERTY_NAMING_TYPE; import org.openapitools.codegen.CodegenConstants.MODEL_PROPERTY_NAMING_TYPE; import org.openapitools.codegen.CodegenConstants.PARAM_NAMING_TYPE; @@ -39,13 +40,183 @@ import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.*; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; +import static org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen.ParameterExpander.ParamStyle.*; import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.underscore; public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig { + + /** + * Help generating code for any kind of URL parameters (path, matrix, query). + *

+ * Generators may use this class when substituting URL-parameter-placeholders + * with generated code: + *

+ *

+ * While parsing placeholders character-by-character, this class helps accumulating these characters and + * building the final placeholder name. + *

+ *

+ * With the placeholder name, this class tries to find the parameter in the operation. + * The class then uses this parameter to build code that is usable by the generator. + *

+ */ + // TODO: this class grew quite large and most code now is specific to TypeScriptAngularClientCodeGen.java. + // => move code-generation to the concrete generator and let the generator pass this as lambda + @SuppressWarnings("StringBufferField") + public static class ParameterExpander { + private static final Pattern JS_QUOTE_PATTERN = Pattern.compile("\""); + private static final String JS_QUOTE_REPLACEMENT = "\\\""; + + /** + * How the parameter is formatted/converted/encoded in the actual request. + *

+ * See e.g. OpenAPI 3.1 spec: Style Values. + *

+ */ + public enum ParamStyle { + matrix, + label, + form, + simple, + spaceDelimited, + pipeDelimited, + deepObject; + + public String asString() { + return name(); + } + } + + /** + * Where the parameter is located in the request. + *

+ * See e.g. OpenAPI 3.1 spec: Parameter Locations + *

+ */ + public enum Location { + query((operation, param) -> operation.queryParams.contains(param), form), + header((operation, param) -> operation.headerParams.contains(param), simple), + path((operation, param) -> operation.pathParams.contains(param), simple), + cookie((operation, param) -> operation.cookieParams.contains(param), form); + + public final ParamStyle defaultStyle; + public final BiPredicate isPresentIn; + + Location(BiPredicate isPresentIn, ParamStyle defaultStyle) { + this.defaultStyle = defaultStyle; + this.isPresentIn = isPresentIn; + } + + public String defaultStyle(@Nullable String style) { + if (style != null && !style.trim().isEmpty()) { + return style; + } + return defaultStyle.asString(); + } + + public static Location fromParam(CodegenOperation op, CodegenParameter param) { + return Arrays.stream(values()) + .filter(v -> v.isPresentIn.test(op, param)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(String.format( + Locale.ROOT, + "Cannot find param ' %s' in operation '%s'", + param, op.operationId + ))); + } + } + + private final StringBuilder parameterName = new StringBuilder(); + private final CodegenOperation op; + private final Function toParameterName; + + public ParameterExpander(CodegenOperation op, Function toParameterName) { + this.op = op; + this.toParameterName = toParameterName; + } + + private void reset() { + parameterName.setLength(0); + } + + public void appendToParameterName(char c) { + parameterName.append(c); + } + + public String buildPathEntry() { + CodegenParameter parameter = findPathParameterByName(); + + String result = ""; + if (parameter != null) { + String generatedParameterName = toParameterName.apply(parameterName.toString()); + result = buildPathEntry(parameter, generatedParameterName); + } + + reset(); + return result; + } + + private String buildPathEntry(CodegenParameter parameter, String generatedParameterName) { + Location location = Location.fromParam(op, parameter); + String style = location.defaultStyle(parameter.style); + + String optsObject = String.format( + Locale.ROOT, + "{name: %s, value: %s, in: %s, style: %s, explode: %s, dataType: %s, dataFormat: %s}", + quotedJSString(parameter.paramName), + generatedParameterName, + quotedJSString(location.name()), + quotedJSString(style), + parameter.isExplode, + quotedJSString(parameter.dataType), + nullableQuotedJSString(parameter.dataFormat) + ); + + String result = String.format(Locale.ROOT, "${this.configuration.encodeParam(%s)}", optsObject); + return result; + } + + private @Nullable CodegenParameter findPathParameterByName() { + for (CodegenParameter param : op.pathParams) { + if (param.baseName.equals(parameterName.toString())) { + return param; + } + } + return null; + } + + private static String quotedJSString(String string) { + String escaped = escapeForQuotedJSString(string); + String result = '"' + escaped + '"'; + return result; + } + + protected static String escapeForQuotedJSString(String string) { + String quoted = JS_QUOTE_PATTERN.matcher(string) + .replaceAll(JS_QUOTE_REPLACEMENT); + + return quoted; + } + + + protected String nullableQuotedJSString(@Nullable String string) { + if (string == null) { + return "undefined"; + } + + String result = quotedJSString(string); + + return result; + } + } + private final Logger LOGGER = LoggerFactory.getLogger(AbstractTypeScriptClientCodegen.class); private static final String X_DISCRIMINATOR_TYPE = "x-discriminator-value"; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularClientCodegen.java index 1b084753a09..5fcf5a708e8 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularClientCodegen.java @@ -20,6 +20,7 @@ package org.openapitools.codegen.languages; import io.swagger.v3.oas.models.media.Schema; import org.openapitools.codegen.*; import org.openapitools.codegen.meta.features.DocumentationFeature; +import org.openapitools.codegen.meta.features.GlobalFeature; import org.openapitools.codegen.model.ModelMap; import org.openapitools.codegen.model.ModelsMap; import org.openapitools.codegen.model.OperationMap; @@ -86,7 +87,10 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode public TypeScriptAngularClientCodegen() { super(); - modifyFeatureSet(features -> features.includeDocumentationFeatures(DocumentationFeature.Readme)); + modifyFeatureSet(features -> features + .includeDocumentationFeatures(DocumentationFeature.Readme) + .includeGlobalFeatures(GlobalFeature.ParameterStyling) + ); this.outputFolder = "generated-code/typescript-angular"; @@ -160,6 +164,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode 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("param.mustache", getIndexDirectory(), "param.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")); @@ -404,6 +409,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode List ops = objs.getOperation(); boolean hasSomeFormParams = false; + boolean hasSomeEncodableParams = false; for (CodegenOperation op : ops) { if (op.getHasFormParams()) { hasSomeFormParams = true; @@ -413,7 +419,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode // 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(); + ParameterExpander paramExpander = new ParameterExpander(op, this::toParamName); int insideCurly = 0; // Iterate through existing string, one character at a time. @@ -422,27 +428,18 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode 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(toParamName(parameterName.toString())); - if (parameter != null && parameter.isDateTime) { - pathBuffer.append(".toISOString()"); - } - pathBuffer.append("))}"); - parameterName.setLength(0); + pathBuffer.append(paramExpander.buildPathEntry()); + hasSomeEncodableParams = true; break; default: char nextChar = op.path.charAt(i); if (insideCurly > 0) { - parameterName.append(nextChar); + paramExpander.appendToParameterName(nextChar); } else { pathBuffer.append(nextChar); } @@ -455,6 +452,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode } operations.put("hasSomeFormParams", hasSomeFormParams); + operations.put("hasSomeEncodableParams", hasSomeEncodableParams); // Add additional filename information for model imports in the services List> imports = operations.getImports(); @@ -467,22 +465,6 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode 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 ModelsMap postProcessModels(ModelsMap objs) { ModelsMap result = super.postProcessModels(objs); diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/README.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/README.mustache index 2a44a92c89a..3a65b9117ef 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/README.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/README.mustache @@ -201,3 +201,26 @@ import { environment } from '../environments/environment'; }) export class AppModule { } ``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache index 53328f40906..3f5870face9 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache @@ -365,7 +365,8 @@ export class {{classname}} { } {{/isResponseFile}} - return this.httpClient.{{httpMethod}}{{^isResponseFile}}<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>{{/isResponseFile}}(`${this.configuration.basePath}{{{path}}}`,{{#isBodyAllowed}} + let localVarPath = `{{{path}}}`; + return this.httpClient.{{httpMethod}}{{^isResponseFile}}<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>{{/isResponseFile}}(`${this.configuration.basePath}${localVarPath}`,{{#isBodyAllowed}} {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}{{#hasFormParams}}localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams{{/hasFormParams}}{{^hasFormParams}}null{{/hasFormParams}}{{/bodyParam}},{{/isBodyAllowed}} { {{#httpContextInOptions}} diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/configuration.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/configuration.mustache index 40aaec67f47..e73eeebf7b6 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/configuration.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/configuration.mustache @@ -1,4 +1,5 @@ import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; export interface {{configurationParametersInterfaceName}} { /** @@ -13,7 +14,18 @@ export interface {{configurationParametersInterfaceName}} { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -35,7 +47,18 @@ export class {{configurationClassName}} { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -51,6 +74,12 @@ export class {{configurationClassName}} { this.basePath = configurationParameters.basePath; this.withCredentials = configurationParameters.withCredentials; this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } if (configurationParameters.credentials) { this.credentials = configurationParameters.credentials; } @@ -157,4 +186,20 @@ export class {{configurationClassName}} { ? value() : value; } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/index.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/index.mustache index c312b70fa3e..104dd3d21e3 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/index.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/index.mustache @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/param.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/param.mustache new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-angular/param.mustache @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/testutils/AssertFile.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/testutils/AssertFile.java index bfdb2452bdf..d46798cd7f5 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/testutils/AssertFile.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/testutils/AssertFile.java @@ -33,7 +33,7 @@ import java.util.Arrays; import java.util.List; import java.util.Locale; -import static org.testng.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.testng.Assert.fail; /** @@ -84,9 +84,10 @@ public class AssertFile { Arrays.sort(actual); } - assertEquals(expected, - actual, - String.format(Locale.ROOT, "Directory content of '%s' and '%s' differ.", expectedDir, actualDir)); + // Use AssertJ as it also prints a diff + assertThat(actual) + .describedAs(String.format(Locale.ROOT, "Directory content of '%s' and '%s' differ.", expectedDir, actualDir)) + .containsExactly(expected); return FileVisitResult.CONTINUE; } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/SharedTypeScriptTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/SharedTypeScriptTest.java index 07f7943b3cf..cdd43b5b090 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/SharedTypeScriptTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/SharedTypeScriptTest.java @@ -16,6 +16,9 @@ import java.util.List; import java.util.Map; import java.util.HashMap; +import static org.openapitools.codegen.typescript.TypeScriptGroups.*; + +@Test(groups = {TYPESCRIPT}) public class SharedTypeScriptTest { @Test public void typesInImportsAreSplittedTest() throws IOException { @@ -93,4 +96,4 @@ public class SharedTypeScriptTest { Assert.assertEquals(mapped, entry.getValue()); } } -} \ No newline at end of file +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptClientCodegenTest.java index 5d53ddf4c88..925a6adcbc5 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptClientCodegenTest.java @@ -20,7 +20,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; - +@Test(groups = {TypeScriptGroups.TYPESCRIPT}) public class TypeScriptClientCodegenTest { @Test public void getTypeDeclarationTest() { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptClientModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptClientModelTest.java index 5a8333b5e5e..5f9b2173ac8 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptClientModelTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptClientModelTest.java @@ -6,11 +6,11 @@ import org.openapitools.codegen.CodegenModel; import org.openapitools.codegen.DefaultCodegen; import org.openapitools.codegen.TestUtils; import org.openapitools.codegen.languages.TypeScriptClientCodegen; -import org.openapitools.codegen.utils.ModelUtils; import org.testng.Assert; import org.testng.annotations.Test; +@Test(groups = {TypeScriptGroups.TYPESCRIPT}) public class TypeScriptClientModelTest { @Test(description = "convert an array oneof model") diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptGroups.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptGroups.java new file mode 100644 index 00000000000..fedc1e5f942 --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/TypeScriptGroups.java @@ -0,0 +1,28 @@ +package org.openapitools.codegen.typescript; + +/** + * TestNG supports grouping using Test Groups. + *
+ *

+ * Using groups also enables running only a subset of tests, e.g. only for the generator you are currently working on. + *

+ *

+ * This speeds up development a lot, especially if run from an IDE with support for TestNG groups + * (e.g. IntelliJ IDEA and derivatives, VS Code, and lots of others) + *

+ *
+ *

Suggested groups/group-names are:

+ *
    + *
  • one per language (e.g.: "typescript") since most generators for one language share lots of code
  • + *
  • one per language + generator (i.e. the generator name, e.g.: "typescript-angular")
  • + *
+ */ +public final class TypeScriptGroups { + public static final String TYPESCRIPT = "typescript"; + public static final String TYPESCRIPT_AURELIA = "typescript-aurelia"; + public static final String TYPESCRIPT_AXIOS = "typescript-axios"; + public static final String TYPESCRIPT_FETCH = "typescript-fetch"; + public static final String TYPESCRIPT_ANGULAR = "typescript-angular"; + public static final String TYPESCRIPT_NESTJS = "typescript-nestjs"; + public static final String TYPESCRIPT_NODE = "typescript-node"; +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/aurelia/TypeScriptAureliaClientOptionsTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/aurelia/TypeScriptAureliaClientOptionsTest.java index be1801e6401..8da6662021f 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/aurelia/TypeScriptAureliaClientOptionsTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/aurelia/TypeScriptAureliaClientOptionsTest.java @@ -21,10 +21,13 @@ import org.openapitools.codegen.AbstractOptionsTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptAureliaClientCodegen; import org.openapitools.codegen.options.TypeScriptAureliaClientOptionsProvider; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_AURELIA}) public class TypeScriptAureliaClientOptionsTest extends AbstractOptionsTest { private TypeScriptAureliaClientCodegen clientCodegen = mock(TypeScriptAureliaClientCodegen.class, mockSettings); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/axios/TypeScriptAxiosClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/axios/TypeScriptAxiosClientCodegenTest.java index e73786adf36..b7040a60171 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/axios/TypeScriptAxiosClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/axios/TypeScriptAxiosClientCodegenTest.java @@ -2,10 +2,12 @@ package org.openapitools.codegen.typescript.axios; import org.openapitools.codegen.CodegenConstants; import org.openapitools.codegen.languages.TypeScriptAxiosClientCodegen; +import org.openapitools.codegen.typescript.TypeScriptGroups; import org.testng.annotations.Test; import static org.testng.Assert.assertEquals; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_AXIOS}) public class TypeScriptAxiosClientCodegenTest { TypeScriptAxiosClientCodegen codegen = new TypeScriptAxiosClientCodegen(); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientCodegenTest.java index 379c2865a4e..34e67404179 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientCodegenTest.java @@ -1,17 +1,22 @@ package org.openapitools.codegen.typescript.fetch; import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.media.*; +import io.swagger.v3.oas.models.media.ArraySchema; +import io.swagger.v3.oas.models.media.MapSchema; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.media.StringSchema; import org.openapitools.codegen.CodegenConstants; import org.openapitools.codegen.SupportingFile; import org.openapitools.codegen.TestUtils; import org.openapitools.codegen.languages.TypeScriptFetchClientCodegen; +import org.openapitools.codegen.typescript.TypeScriptGroups; import org.openapitools.codegen.utils.ModelUtils; import org.testng.Assert; import org.testng.annotations.Test; import static org.assertj.core.api.Assertions.assertThat; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_FETCH}) public class TypeScriptFetchClientCodegenTest { @Test public void testSnapshotVersion() { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientOptionsTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientOptionsTest.java index 6d3f50e7be0..9c4e471603c 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientOptionsTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientOptionsTest.java @@ -21,10 +21,13 @@ import org.openapitools.codegen.AbstractOptionsTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptFetchClientCodegen; import org.openapitools.codegen.options.TypeScriptFetchClientOptionsProvider; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_FETCH}) public class TypeScriptFetchClientOptionsTest extends AbstractOptionsTest { private TypeScriptFetchClientCodegen clientCodegen = mock(TypeScriptFetchClientCodegen.class, mockSettings); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchModelTest.java index d1af770e2cd..e73a0988bbb 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchModelTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchModelTest.java @@ -26,6 +26,7 @@ import org.openapitools.codegen.CodegenProperty; import org.openapitools.codegen.DefaultCodegen; import org.openapitools.codegen.TestUtils; import org.openapitools.codegen.languages.TypeScriptFetchClientCodegen; +import org.openapitools.codegen.typescript.TypeScriptGroups; import org.testng.Assert; import org.testng.annotations.Test; @@ -45,6 +46,7 @@ import static io.swagger.codegen.languages.helpers.ExtensionHelper.getBooleanVal import static io.swagger.codegen.utils.ModelUtils.updateCodegenPropertyEnum; */ +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_FETCH}) @SuppressWarnings("static-method") public class TypeScriptFetchModelTest { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientCodegenTest.java index 61231472997..a28daaaa0fa 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientCodegenTest.java @@ -11,6 +11,7 @@ import io.swagger.v3.oas.models.responses.ApiResponses; import org.openapitools.codegen.*; import org.openapitools.codegen.config.CodegenConfigurator; import org.openapitools.codegen.languages.TypeScriptAngularClientCodegen; +import org.openapitools.codegen.typescript.TypeScriptGroups; import org.testng.Assert; import org.testng.annotations.Test; @@ -21,6 +22,7 @@ import java.util.HashMap; import java.util.Map; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_ANGULAR}) public class TypeScriptAngularClientCodegenTest { @Test public void toVarName() { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientOptionsTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientOptionsTest.java index 38b1f0ee4d0..79562065691 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientOptionsTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientOptionsTest.java @@ -21,10 +21,13 @@ import org.openapitools.codegen.AbstractOptionsTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptAngularClientCodegen; import org.openapitools.codegen.options.TypeScriptAngularClientOptionsProvider; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_ANGULAR}) public class TypeScriptAngularClientOptionsTest extends AbstractOptionsTest { private TypeScriptAngularClientCodegen clientCodegen = mock(TypeScriptAngularClientCodegen.class, mockSettings); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularModelTest.java index 0d9e8cb8f35..0994c14a82f 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularModelTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularModelTest.java @@ -27,6 +27,7 @@ import org.openapitools.codegen.DefaultCodegen; import org.openapitools.codegen.TestUtils; import org.openapitools.codegen.languages.TypeScriptAngularClientCodegen; import org.openapitools.codegen.languages.TypeScriptFetchClientCodegen; +import org.openapitools.codegen.typescript.TypeScriptGroups; import org.testng.Assert; import org.testng.annotations.Test; @@ -38,6 +39,7 @@ import java.time.ZoneOffset; import java.util.Date; import java.util.Locale; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_ANGULAR}) @SuppressWarnings("static-method") public class TypeScriptAngularModelTest { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularAdditionalPropertiesIntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularAdditionalPropertiesIntegrationTest.java index 64ad61af317..ee87da560e3 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularAdditionalPropertiesIntegrationTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularAdditionalPropertiesIntegrationTest.java @@ -21,12 +21,23 @@ import org.openapitools.codegen.AbstractIntegrationTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptAngularClientCodegen; import org.openapitools.codegen.testutils.IntegrationTestPathsConfig; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; +import java.io.IOException; import java.util.HashMap; import java.util.Map; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_ANGULAR}) public class TypescriptAngularAdditionalPropertiesIntegrationTest extends AbstractIntegrationTest { + { + // when running repeatedly from an IDE, some files do not get overwritten + // and thus are missing from the FILES metadata. + // Since metadata-verification is not the core responsibility of this test: disable it. + generateMetadata = false; + } + @Override protected CodegenConfig getCodegenConfig() { return new TypeScriptAngularClientCodegen(); @@ -46,4 +57,11 @@ public class TypescriptAngularAdditionalPropertiesIntegrationTest extends Abstra protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { return new IntegrationTestPathsConfig("typescript/additional-properties"); } + + @Test + @Override + public void generatesCorrectDirectoryStructure() throws IOException { + // test are currently disabled in Superclass + super.generatesCorrectDirectoryStructure(); + } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularApiVersionTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularApiVersionTest.java index a5779813146..399fe90a875 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularApiVersionTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularApiVersionTest.java @@ -3,9 +3,11 @@ package org.openapitools.codegen.typescript.typescriptangular; import io.swagger.v3.oas.models.OpenAPI; import org.openapitools.codegen.TestUtils; import org.openapitools.codegen.languages.TypeScriptAngularClientCodegen; +import org.openapitools.codegen.typescript.TypeScriptGroups; import org.testng.Assert; import org.testng.annotations.Test; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_ANGULAR}) public class TypescriptAngularApiVersionTest { @Test(description = "tests if API version specification is used if no version is provided in additional properties") diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularArrayAndObjectIntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularArrayAndObjectIntegrationTest.java index 4a2bab73c2b..9bbb9ea4ef5 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularArrayAndObjectIntegrationTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularArrayAndObjectIntegrationTest.java @@ -21,12 +21,23 @@ import org.openapitools.codegen.AbstractIntegrationTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptAngularClientCodegen; import org.openapitools.codegen.testutils.IntegrationTestPathsConfig; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; +import java.io.IOException; import java.util.HashMap; import java.util.Map; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_ANGULAR}) public class TypescriptAngularArrayAndObjectIntegrationTest extends AbstractIntegrationTest { + { + // when running repeatedly from an IDE, some files do not get overwritten + // and thus are missing from the FILES metadata. + // Since metadata-verification is not the core responsibility of this test: disable it. + generateMetadata = false; + } + @Override protected CodegenConfig getCodegenConfig() { return new TypeScriptAngularClientCodegen(); @@ -46,4 +57,11 @@ public class TypescriptAngularArrayAndObjectIntegrationTest extends AbstractInte protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { return new IntegrationTestPathsConfig("typescript/array-and-object"); } + + @Test + @Override + public void generatesCorrectDirectoryStructure() throws IOException { + // test are currently disabled in Superclass + super.generatesCorrectDirectoryStructure(); + } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularParamsStrategyCustomIntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularParamsStrategyCustomIntegrationTest.java new file mode 100644 index 00000000000..ceac06d46ff --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularParamsStrategyCustomIntegrationTest.java @@ -0,0 +1,66 @@ +/* + * 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.typescript.typescriptangular; + +import org.openapitools.codegen.AbstractIntegrationTest; +import org.openapitools.codegen.CodegenConfig; +import org.openapitools.codegen.languages.TypeScriptAngularClientCodegen; +import org.openapitools.codegen.testutils.IntegrationTestPathsConfig; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_ANGULAR}) +public class TypescriptAngularParamsStrategyCustomIntegrationTest extends AbstractIntegrationTest { + + { + // when running repeatedly from an IDE, some files do not get overwritten + // and thus are missing from the FILES metadata. + // Since metadata-verification is not the core responsibility of this test: disable it. + generateMetadata = false; + } + + @Override + protected CodegenConfig getCodegenConfig() { + return new TypeScriptAngularClientCodegen(); + } + + @Override + protected Map configProperties() { + Map properties = new HashMap<>(); + properties.put("npmName", "custom-path-params-integration-test"); + properties.put("npmVersion", "1.0.3"); + properties.put("snapshot", "false"); + + return properties; + } + + @Override + protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { + return new IntegrationTestPathsConfig("typescript/custom-path-params"); + } + + @Test + @Override + public void generatesCorrectDirectoryStructure() throws IOException { + // test are currently disabled in Superclass + super.generatesCorrectDirectoryStructure(); + } +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularPetstoreIntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularPetstoreIntegrationTest.java index 4a4fddf4c4a..251463ce653 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularPetstoreIntegrationTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularPetstoreIntegrationTest.java @@ -21,12 +21,23 @@ import org.openapitools.codegen.AbstractIntegrationTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptAngularClientCodegen; import org.openapitools.codegen.testutils.IntegrationTestPathsConfig; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; +import java.io.IOException; import java.util.HashMap; import java.util.Map; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_ANGULAR}) public class TypescriptAngularPetstoreIntegrationTest extends AbstractIntegrationTest { + { + // when running repeatedly from an IDE, some files do not get overwritten + // and thus are missing from the FILES metadata. + // Since metadata-verification is not the core responsibility of this test: disable it. + generateMetadata = false; + } + @Override protected CodegenConfig getCodegenConfig() { return new TypeScriptAngularClientCodegen(); @@ -46,4 +57,11 @@ public class TypescriptAngularPetstoreIntegrationTest extends AbstractIntegratio protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { return new IntegrationTestPathsConfig("typescript/petstore"); } + + @Test + @Override + public void generatesCorrectDirectoryStructure() throws IOException { + // test are currently disabled in Superclass + super.generatesCorrectDirectoryStructure(); + } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypeScriptNestjsClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypeScriptNestjsClientCodegenTest.java index 43775c64132..72aae1b236e 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypeScriptNestjsClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypeScriptNestjsClientCodegenTest.java @@ -10,10 +10,12 @@ 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.openapitools.codegen.typescript.TypeScriptGroups; import org.testng.Assert; import org.testng.annotations.Test; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_NESTJS}) public class TypeScriptNestjsClientCodegenTest { @Test public void testModelFileSuffix() { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypeScriptNestjsClientOptionsTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypeScriptNestjsClientOptionsTest.java index ba042c8471f..7b812a7eb37 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypeScriptNestjsClientOptionsTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypeScriptNestjsClientOptionsTest.java @@ -20,10 +20,13 @@ import org.openapitools.codegen.AbstractOptionsTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen; import org.openapitools.codegen.options.TypeScriptNestjsClientOptionsProvider; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_NESTJS}) public class TypeScriptNestjsClientOptionsTest extends AbstractOptionsTest { private TypeScriptNestjsClientCodegen clientCodegen = mock(TypeScriptNestjsClientCodegen.class, mockSettings); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypeScriptNestjsModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypeScriptNestjsModelTest.java index 1ea2ed86c06..4338260cfdf 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypeScriptNestjsModelTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypeScriptNestjsModelTest.java @@ -25,9 +25,11 @@ import org.openapitools.codegen.CodegenProperty; import org.openapitools.codegen.DefaultCodegen; import org.openapitools.codegen.TestUtils; import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen; +import org.openapitools.codegen.typescript.TypeScriptGroups; import org.testng.Assert; import org.testng.annotations.Test; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_NESTJS}) @SuppressWarnings("static-method") public class TypeScriptNestjsModelTest { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsAdditionalPropertiesIntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsAdditionalPropertiesIntegrationTest.java index e0ab5cd60cf..0844344ae9c 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsAdditionalPropertiesIntegrationTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsAdditionalPropertiesIntegrationTest.java @@ -20,10 +20,13 @@ import org.openapitools.codegen.AbstractIntegrationTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen; import org.openapitools.codegen.testutils.IntegrationTestPathsConfig; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; import java.util.HashMap; import java.util.Map; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_NESTJS}) public class TypescriptNestjsAdditionalPropertiesIntegrationTest extends AbstractIntegrationTest { @Override diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsApiVersionTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsApiVersionTest.java index e767a1eeb07..8cafe9c97db 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsApiVersionTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsApiVersionTest.java @@ -3,9 +3,11 @@ 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.openapitools.codegen.typescript.TypeScriptGroups; import org.testng.Assert; import org.testng.annotations.Test; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_NESTJS}) public class TypescriptNestjsApiVersionTest { @Test(description = "tests if API version specification is used if no version is provided in additional properties") diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsArrayAndObjectIntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsArrayAndObjectIntegrationTest.java index 15d19d42af2..af12b8b4482 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsArrayAndObjectIntegrationTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsArrayAndObjectIntegrationTest.java @@ -20,10 +20,13 @@ import org.openapitools.codegen.AbstractIntegrationTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen; import org.openapitools.codegen.testutils.IntegrationTestPathsConfig; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; import java.util.HashMap; import java.util.Map; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_NESTJS}) public class TypescriptNestjsArrayAndObjectIntegrationTest extends AbstractIntegrationTest { @Override diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsPetstoreIntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsPetstoreIntegrationTest.java index 30e2e2cee79..285fe88b464 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsPetstoreIntegrationTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnestjs/TypescriptNestjsPetstoreIntegrationTest.java @@ -20,10 +20,13 @@ import org.openapitools.codegen.AbstractIntegrationTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen; import org.openapitools.codegen.testutils.IntegrationTestPathsConfig; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; import java.util.HashMap; import java.util.Map; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_NESTJS}) public class TypescriptNestjsPetstoreIntegrationTest extends AbstractIntegrationTest { @Override diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeClientCodegenTest.java index dacc57d2f70..2a9843669a1 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeClientCodegenTest.java @@ -11,12 +11,14 @@ import org.openapitools.codegen.model.ModelMap; import org.openapitools.codegen.model.ModelsMap; import org.openapitools.codegen.model.OperationMap; import org.openapitools.codegen.model.OperationsMap; +import org.openapitools.codegen.typescript.TypeScriptGroups; import org.testng.Assert; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.util.*; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_NODE}) public class TypeScriptNodeClientCodegenTest { private TypeScriptNodeClientCodegen codegen; diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeClientOptionsTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeClientOptionsTest.java index 680759c870c..61999253c9d 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeClientOptionsTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeClientOptionsTest.java @@ -21,10 +21,13 @@ import org.openapitools.codegen.AbstractOptionsTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptNodeClientCodegen; import org.openapitools.codegen.options.TypeScriptNodeClientOptionsProvider; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_NODE}) public class TypeScriptNodeClientOptionsTest extends AbstractOptionsTest { private TypeScriptNodeClientCodegen clientCodegen = mock(TypeScriptNodeClientCodegen.class, mockSettings); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeModelTest.java index efacb8b5ff9..42b7fbe1b42 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeModelTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeModelTest.java @@ -18,17 +18,16 @@ package org.openapitools.codegen.typescript.typescriptnode; 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.TypeScriptFetchClientCodegen; import org.openapitools.codegen.languages.TypeScriptNodeClientCodegen; +import org.openapitools.codegen.typescript.TypeScriptGroups; import org.testng.Assert; import org.testng.annotations.Test; @@ -40,6 +39,7 @@ import java.time.ZoneOffset; import java.util.Date; import java.util.Locale; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_NODE}) @SuppressWarnings("static-method") public class TypeScriptNodeModelTest { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypescriptNodeES5IntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypescriptNodeES5IntegrationTest.java index 8b200db6f33..b7fc1bcd368 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypescriptNodeES5IntegrationTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypescriptNodeES5IntegrationTest.java @@ -21,10 +21,13 @@ import org.openapitools.codegen.AbstractIntegrationTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptNodeClientCodegen; import org.openapitools.codegen.testutils.IntegrationTestPathsConfig; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; import java.util.HashMap; import java.util.Map; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_NODE}) public class TypescriptNodeES5IntegrationTest extends AbstractIntegrationTest { @Override diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypescriptNodeEnumIntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypescriptNodeEnumIntegrationTest.java index e695fbe04bf..d5490934a9f 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypescriptNodeEnumIntegrationTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypescriptNodeEnumIntegrationTest.java @@ -20,10 +20,13 @@ import org.openapitools.codegen.AbstractIntegrationTest; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.languages.TypeScriptNodeClientCodegen; import org.openapitools.codegen.testutils.IntegrationTestPathsConfig; +import org.openapitools.codegen.typescript.TypeScriptGroups; +import org.testng.annotations.Test; import java.util.HashMap; import java.util.Map; +@Test(groups = {TypeScriptGroups.TYPESCRIPT, TypeScriptGroups.TYPESCRIPT_NODE}) public class TypescriptNodeEnumIntegrationTest extends AbstractIntegrationTest { @Override diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/.gitignore b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/.gitignore index 35e2fb2b02e..149b5765472 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/.gitignore +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/.gitignore @@ -1,3 +1,4 @@ wwwroot/*.js node_modules typings +dist diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/.openapi-generator-ignore b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/.openapi-generator-ignore deleted file mode 100644 index deed424f8a1..00000000000 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/.openapi-generator-ignore +++ /dev/null @@ -1,23 +0,0 @@ -# Swagger Codegen Ignore -# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen - -# 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 Swagger Codegen 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 diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/LICENSE b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/LICENSE deleted file mode 100644 index 3f4d322ebd7..00000000000 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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. diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/README.md b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/README.md index 3ae010d2a43..d46ff5c06b9 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/README.md +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/README.md @@ -2,7 +2,7 @@ ### Building -To build and compile the typescript sources to javascript use: +To install the required dependencies and to build the typescript sources run: ``` npm install npm run build @@ -10,11 +10,11 @@ npm run build ### publishing -First build the package than run ```npm publish``` +First build the package then run ```npm publish dist``` (don't forget to specify the `dist` folder!) ### consuming -navigate to the folder of your consuming project and run one of next commando's. +Navigate to the folder of your consuming project and run one of next commands. _published:_ @@ -22,23 +22,205 @@ _published:_ npm install additionalPropertiesTest@1.0.2 --save ``` -_unPublished (not recommended):_ +_without publishing (not recommended):_ ``` -npm install PATH_TO_GENERATED_PACKAGE --save +npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save ``` -In your angular2 project: +_It's important to take the tgz file, otherwise you'll get trouble with links on windows_ + +_using `npm link`:_ + +In PATH_TO_GENERATED_PACKAGE/dist: +``` +npm link +``` + +In your project: +``` +npm link additionalPropertiesTest +``` + +__Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. +Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Published packages are not effected by this issue. + + +#### General usage + +In your Angular project: + + +``` +// without configuring providers +import { ApiModule } from 'additionalPropertiesTest'; +import { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + ApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers +import { ApiModule, Configuration, ConfigurationParameters } from 'additionalPropertiesTest'; + +export function apiConfigFactory (): Configuration { + const params: ConfigurationParameters = { + // set configuration parameters here. + } + return new Configuration(params); +} + +@NgModule({ + imports: [ ApiModule.forRoot(apiConfigFactory) ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers with an authentication service that manages your access tokens +import { ApiModule, Configuration } from 'additionalPropertiesTest'; + +@NgModule({ + imports: [ ApiModule ], + declarations: [ AppComponent ], + providers: [ + { + provide: Configuration, + useFactory: (authService: AuthService) => new Configuration( + { + basePath: environment.apiUrl, + accessToken: authService.getAccessToken.bind(authService) + } + ), + deps: [AuthService], + multi: false + } + ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +import { DefaultApi } from 'additionalPropertiesTest'; + +export class AppComponent { + constructor(private apiGateway: DefaultApi) { } +} +``` + +Note: The ApiModule is restricted to being instantiated once app wide. +This is to ensure that all services are treated as singletons. + +#### Using multiple OpenAPI files / APIs / ApiModules +In order to use multiple `ApiModules` generated from different OpenAPI 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 { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + ApiModule, + OtherApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ] +}) +export class AppModule { + +} +``` -TODO: paste example. ### Set service base path -If different than the generated base path, during app bootstrap, you can provide the base path to your service. +If different than the generated base path, during app bootstrap, you can provide the base path to your service. ``` -import { BASE_PATH } from './path-to-swagger-gen-service/index'; +import { BASE_PATH } from 'additionalPropertiesTest'; bootstrap(AppComponent, [ { provide: BASE_PATH, useValue: 'https://your-web-service.com' }, ]); -``` +``` +or + +``` +import { BASE_PATH } from 'additionalPropertiesTest'; + +@NgModule({ + imports: [], + declarations: [ AppComponent ], + providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + + +#### Using @angular/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 'additionalPropertiesTest'; +import { environment } from '../environments/environment'; + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ ], + providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api.module.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api.module.ts index bb9f292627a..31f437b388c 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api.module.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api.module.ts @@ -1,21 +1,31 @@ -import { NgModule, ModuleWithProviders } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { HttpModule } from '@angular/http'; +import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core'; import { Configuration } from './configuration'; +import { HttpClient } from '@angular/common/http'; import { UserService } from './api/user.service'; @NgModule({ - imports: [ CommonModule, HttpModule ], + imports: [], declarations: [], exports: [], - providers: [ UserService ] + providers: [] }) export class ApiModule { - public static forConfig(configuration: Configuration): ModuleWithProviders { + public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders { return { ngModule: ApiModule, - providers: [ {provide: Configuration, useValue: configuration}] + providers: [ { provide: Configuration, useFactory: configurationFactory } ] + }; + } + + constructor( @Optional() @SkipSelf() parentModule: ApiModule, + @Optional() http: HttpClient) { + if (parentModule) { + throw new Error('ApiModule is already loaded. Import in your base AppModule only.'); + } + if (!http) { + throw new Error('You need to import the HttpClientModule in your AppModule! \n' + + 'See also https://github.com/angular/angular/issues/20575'); } } } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api/api.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api/api.ts index e17ee5c7aca..e5e59a3e181 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api/api.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api/api.ts @@ -1 +1,3 @@ export * from './user.service'; +import { UserService } from './user.service'; +export const APIS = [UserService]; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api/user.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api/user.service.ts index 1ff0ea1ffc5..3741811e01f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api/user.service.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api/user.service.ts @@ -1,166 +1,222 @@ /** - * Swagger Additional Properties + * OpenAPI Additional Properties * This is a test spec * - * OpenAPI spec version: 1.0.0 - * Contact: apiteam@swagger.io + * The version of the OpenAPI document: 1.0.0 + * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - -import { Inject, Injectable, Optional } from '@angular/core'; -import { Http, Headers, URLSearchParams } from '@angular/http'; -import { RequestMethod, RequestOptions, RequestOptionsArgs } from '@angular/http'; -import { Response, ResponseContentType } from '@angular/http'; - -import { Observable } from 'rxjs/Observable'; -import '../rxjs-operators'; - -import { User } from '../model/user'; - -import { BASE_PATH } from '../variables'; -import { Configuration } from '../configuration'; - /* tslint:disable:no-unused-variable member-ordering */ +import { Inject, Injectable, Optional } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpParams, + HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + } from '@angular/common/http'; +import { CustomHttpParameterCodec } from '../encoder'; +import { Observable } from 'rxjs'; -@Injectable() +// @ts-ignore +import { User } from '../model/user'; + +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + + + +@Injectable({ + providedIn: 'root' +}) export class UserService { - protected basePath = 'http://additional-properties.swagger.io/v2'; - public defaultHeaders: Headers = new Headers(); - public configuration: Configuration = new Configuration(); - constructor(protected http: Http, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) { - if (basePath) { - this.basePath = basePath; - } + protected basePath = 'http://additional-properties.swagger.io/v2'; + public defaultHeaders = new HttpHeaders(); + public configuration = new Configuration(); + public encoder: HttpParameterCodec; + + constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { if (configuration) { this.configuration = configuration; - this.basePath = basePath || configuration.basePath || this.basePath; } + if (typeof this.configuration.basePath !== 'string') { + if (Array.isArray(basePath) && basePath.length > 0) { + basePath = basePath[0]; + } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; + } + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + + + // @ts-ignore + private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { + if (typeof value === "object" && value instanceof Date === false) { + httpParams = this.addToHttpParamsRecursive(httpParams, value); + } else { + httpParams = this.addToHttpParamsRecursive(httpParams, value, key); + } + return httpParams; + } + + private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { + if (value == null) { + return httpParams; + } + + if (typeof value === "object") { + if (Array.isArray(value)) { + (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); + } else if (value instanceof Date) { + if (key != null) { + httpParams = httpParams.append(key, (value as Date).toISOString().substr(0, 10)); + } else { + throw Error("key may not be null if value is Date"); + } + } else { + Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( + httpParams, value[k], key != null ? `${key}.${k}` : k)); + } + } else if (key != null) { + httpParams = httpParams.append(key, value); + } else { + throw Error("key may not be null if value is not object or array"); + } + return httpParams; } /** * Add a new User to the store - * * @param body User 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 addUser(body?: User, extraHttpRequestParams?: any): Observable<{}> { - return this.addUserWithHttpInfo(body, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); + public addUser(body?: { [key: string]: string; }, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public addUser(body?: { [key: string]: string; }, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public addUser(body?: { [key: string]: string; }, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public addUser(body?: { [key: string]: string; }, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + 'application/json' + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, + body, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * Update an existing User - * * @param body User 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 updateUser(body?: User, extraHttpRequestParams?: any): Observable<{}> { - return this.updateUserWithHttpInfo(body, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } + public updateUser(body?: { [key: string]: string; }, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public updateUser(body?: { [key: string]: string; }, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public updateUser(body?: { [key: string]: string; }, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public updateUser(body?: { [key: string]: string; }, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + let localVarHeaders = this.defaultHeaders; - /** - * Add a new User to the store - * - * @param body User object that needs to be added to the store - */ - public addUserWithHttpInfo(body?: User, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/user`; + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } // to determine the Content-Type header - let consumes: string[] = [ + const consumes: string[] = [ 'application/json' ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } - // to determine the Accept header - let produces: string[] = [ - 'application/json' - ]; - - + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } - headers.set('Content-Type', 'application/json'); - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Post, - headers: headers, - body: body == null ? '' : JSON.stringify(body), // https://github.com/angular/angular/issues/10612 - search: queryParameters, - responseType: ResponseContentType.Json - }); - - return this.http.request(path, requestOptions); - } - - /** - * Update an existing User - * - * @param body User object that needs to be added to the store - */ - public updateUserWithHttpInfo(body?: User, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/user`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - - - // to determine the Content-Type header - let consumes: string[] = [ - 'application/json' - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/json' - ]; - - - - headers.set('Content-Type', 'application/json'); - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Put, - headers: headers, - body: body == null ? '' : JSON.stringify(body), // https://github.com/angular/angular/issues/10612 - search: queryParameters, - responseType: ResponseContentType.Json - }); - - return this.http.request(path, requestOptions); + let localVarPath = `/user`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, + body, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/configuration.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/configuration.ts index ec087d2b0c8..d38a4c153f2 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/configuration.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/configuration.ts @@ -1,24 +1,166 @@ +import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; + export interface ConfigurationParameters { - apiKey?: string; - username?: string; - password?: string; - accessToken?: string; - basePath?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ + encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; + /** + * The keys are the names in the securitySchemes section of the OpenAPI + * document. They should map to the value used for authentication + * minus any standard prefixes such as 'Basic' or 'Bearer'. + */ + credentials?: {[ key: string ]: string | (() => string | undefined)}; } export class Configuration { - apiKey: string; - username: string; - password: string; - accessToken: string; - basePath: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ + encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; + /** + * The keys are the names in the securitySchemes section of the OpenAPI + * document. They should map to the value used for authentication + * minus any standard prefixes such as 'Basic' or 'Bearer'. + */ + credentials: {[ key: string ]: string | (() => string | undefined)}; + constructor(configurationParameters: 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; + this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } + if (configurationParameters.credentials) { + this.credentials = configurationParameters.credentials; + } + else { + this.credentials = {}; + } + } - constructor(configurationParameters: ConfigurationParameters = {}) { - this.apiKey = configurationParameters.apiKey; - this.username = configurationParameters.username; - this.password = configurationParameters.password; - this.accessToken = configurationParameters.accessToken; - this.basePath = configurationParameters.basePath; - } + /** + * 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 undefined if no selection could be made. + */ + public selectHeaderContentType (contentTypes: string[]): string | undefined { + if (contentTypes.length === 0) { + return undefined; + } + + const type = contentTypes.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return contentTypes[0]; + } + return type; + } + + /** + * Select the correct accept content-type to use for a request. + * Uses {@link 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 undefined if no selection could be made. + */ + public selectHeaderAccept(accepts: string[]): string | undefined { + if (accepts.length === 0) { + return undefined; + } + + const type = accepts.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return accepts[0]; + } + return type; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } + + public lookupCredential(key: string): string | undefined { + const value = this.credentials[key]; + return typeof value === 'function' + ? value() + : value; + } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/encoder.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/encoder.ts new file mode 100644 index 00000000000..138c4d5cf2c --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/encoder.ts @@ -0,0 +1,20 @@ +import { HttpParameterCodec } from '@angular/common/http'; + +/** + * Custom HttpParameterCodec + * Workaround for https://github.com/angular/angular/issues/18261 + */ +export class CustomHttpParameterCodec implements HttpParameterCodec { + encodeKey(k: string): string { + return encodeURIComponent(k); + } + encodeValue(v: string): string { + return encodeURIComponent(v); + } + decodeKey(k: string): string { + return decodeURIComponent(k); + } + decodeValue(v: string): string { + return decodeURIComponent(v); + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/git_push.sh b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/git_push.sh index 484e8cc0033..67b52e22d7f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/git_push.sh +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/git_push.sh @@ -1,11 +1,17 @@ #!/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 swagger-petstore-perl "minor update" +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" git_user_id=$1 git_repo_id=$2 release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi if [ "$git_user_id" = "" ]; then git_user_id="" @@ -28,7 +34,7 @@ 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. +# Commits the tracked changes and prepares them to be pushed to a remote repository. git commit -m "$release_note" # Sets the new remote @@ -37,9 +43,9 @@ if [ "$git_remote" = "" ]; then # git remote not defined if [ "$GIT_TOKEN" = "" ]; then echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." - git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + 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}"@github.com/${git_user_id}/${git_repo_id}.git + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git fi fi @@ -47,6 +53,5 @@ fi git pull origin master # Pushes (Forces) the changes in the local repository up to the remote repository -echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" git push origin master 2>&1 | grep -v 'To https' - diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/index.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/index.ts index c312b70fa3e..104dd3d21e3 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/index.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/index.ts @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/model/user.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/model/user.ts index 6a023abeea7..a62b83bbe77 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/model/user.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/model/user.ts @@ -1,37 +1,24 @@ /** - * Swagger Additional Properties + * OpenAPI Additional Properties * This is a test spec * - * OpenAPI spec version: 1.0.0 - * Contact: apiteam@swagger.io + * The version of the OpenAPI document: 1.0.0 + * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ +export interface User { + [key: string]: string | any; -export interface User { - [key: string]: string | any; id?: number; - /** * User Status */ userStatus?: number; - } + diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/ng-package.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/ng-package.json new file mode 100644 index 00000000000..3b17900dc9c --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/ng-package.json @@ -0,0 +1,6 @@ +{ + "$schema": "./node_modules/ng-packagr/ng-package.schema.json", + "lib": { + "entryFile": "index.ts" + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/package.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/package.json index 54e4c8a12a1..31e050fb002 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/package.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/package.json @@ -1,38 +1,34 @@ { "name": "additionalPropertiesTest", "version": "1.0.2", - "description": "swagger client for additionalPropertiesTest", - "author": "Swagger Codegen Contributors", + "description": "OpenAPI client for additionalPropertiesTest", + "author": "OpenAPI-Generator Contributors", + "repository": { + "type": "git", + "url": "https:////.git" + }, "keywords": [ - "swagger-client" + "openapi-client", + "openapi-generator" ], - "license": "Apache-2.0", - "main": "dist/index.js", - "typings": "dist/index.d.ts", + "license": "Unlicense", "scripts": { - "build": "typings install && tsc --outDir dist/" + "build": "ng-packagr -p ng-package.json" }, "peerDependencies": { - "@angular/core": "^2.0.0", - "@angular/http": "^2.0.0", - "@angular/common": "^2.0.0", - "@angular/compiler": "^2.0.0", - "core-js": "^2.4.0", - "reflect-metadata": "^0.1.3", - "rxjs": "5.0.0-beta.12", - "zone.js": "^0.6.17" + "@angular/core": "^14.0.5", + "rxjs": "^7.5.5" }, "devDependencies": { - "@angular/core": "^2.0.0", - "@angular/http": "^2.0.0", - "@angular/common": "^2.0.0", - "@angular/compiler": "^2.0.0", - "@angular/platform-browser": "^2.0.0", - "core-js": "^2.4.0", + "@angular/common": "^14.0.5", + "@angular/compiler": "^14.0.5", + "@angular/compiler-cli": "^14.0.5", + "@angular/core": "^14.0.5", + "@angular/platform-browser": "^14.0.5", + "ng-packagr": "^14.0.2", "reflect-metadata": "^0.1.3", - "rxjs": "5.0.0-beta.12", - "zone.js": "^0.6.17", - "typescript": "^4.0", - "typings": "^1.3.2" - } -} + "rxjs": "^7.5.5", + "tsickle": "^0.46.3", + "typescript": ">=4.6.0 <=4.8.0", + "zone.js": "^0.11.5" + }} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/param.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/rxjs-operators.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/rxjs-operators.ts deleted file mode 100644 index 5659cd0694f..00000000000 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/rxjs-operators.ts +++ /dev/null @@ -1,11 +0,0 @@ -// RxJS imports according to https://angular.io/docs/ts/latest/guide/server-communication.html#!#rxjs - -// See node_module/rxjs/Rxjs.js -// Import just the rxjs statics and operators we need for THIS app. - -// Statics -import 'rxjs/add/observable/throw'; - -// Operators -import 'rxjs/add/operator/catch'; -import 'rxjs/add/operator/map'; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/tsconfig.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/tsconfig.json index e1f949692b6..c01ebe255d4 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/tsconfig.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/tsconfig.json @@ -1,28 +1,28 @@ { - "compilerOptions": { - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "noImplicitAny": false, - "suppressImplicitAnyIndexErrors": true, - "target": "es5", - "module": "commonjs", - "moduleResolution": "node", - "removeComments": true, - "sourceMap": true, - "outDir": "./lib", - "noLib": false, - "declaration": true - }, - "exclude": [ - "node_modules", - "typings/main.d.ts", - "typings/main", - "lib", - "dist" - ], - "filesGlob": [ - "./model/*.ts", - "./api/*.ts", - "typings/browser.d.ts" - ] + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "noImplicitAny": false, + "suppressImplicitAnyIndexErrors": true, + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "removeComments": true, + "sourceMap": true, + "outDir": "./dist", + "noLib": false, + "declaration": true, + "lib": [ "es6", "dom" ], + "typeRoots": [ + "node_modules/@types" + ] + }, + "exclude": [ + "node_modules", + "dist" + ], + "filesGlob": [ + "./model/*.ts", + "./api/*.ts" + ] } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/typings.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/typings.json deleted file mode 100644 index 507c40e5cbe..00000000000 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/typings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "globalDependencies": { - "core-js": "registry:dt/core-js#0.0.0+20160725163759" - } -} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/variables.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/variables.ts index 27b987e9b23..6fe58549f39 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/variables.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/variables.ts @@ -1,3 +1,9 @@ -import { OpaqueToken } from '@angular/core'; +import { InjectionToken } from '@angular/core'; -export const BASE_PATH = new OpaqueToken('basePath'); \ No newline at end of file +export const BASE_PATH = new InjectionToken('basePath'); +export const COLLECTION_FORMATS = { + 'csv': ',', + 'tsv': ' ', + 'ssv': ' ', + 'pipes': '|' +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/.gitignore b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/.gitignore index 35e2fb2b02e..149b5765472 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/.gitignore +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/.gitignore @@ -1,3 +1,4 @@ wwwroot/*.js node_modules typings +dist diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/.openapi-generator-ignore b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/.openapi-generator-ignore deleted file mode 100644 index deed424f8a1..00000000000 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/.openapi-generator-ignore +++ /dev/null @@ -1,23 +0,0 @@ -# Swagger Codegen Ignore -# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen - -# 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 Swagger Codegen 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 diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/LICENSE b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/LICENSE deleted file mode 100644 index 3f4d322ebd7..00000000000 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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. diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/README.md b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/README.md index 0dead26a31e..9d5891ab4e1 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/README.md +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/README.md @@ -2,7 +2,7 @@ ### Building -To build and compile the typescript sources to javascript use: +To install the required dependencies and to build the typescript sources run: ``` npm install npm run build @@ -10,11 +10,11 @@ npm run build ### publishing -First build the package than run ```npm publish``` +First build the package then run ```npm publish dist``` (don't forget to specify the `dist` folder!) ### consuming -navigate to the folder of your consuming project and run one of next commando's. +Navigate to the folder of your consuming project and run one of next commands. _published:_ @@ -22,23 +22,205 @@ _published:_ npm install arrayAndAnyTest@1.0.2 --save ``` -_unPublished (not recommended):_ +_without publishing (not recommended):_ ``` -npm install PATH_TO_GENERATED_PACKAGE --save +npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save ``` -In your angular2 project: +_It's important to take the tgz file, otherwise you'll get trouble with links on windows_ + +_using `npm link`:_ + +In PATH_TO_GENERATED_PACKAGE/dist: +``` +npm link +``` + +In your project: +``` +npm link arrayAndAnyTest +``` + +__Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. +Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Published packages are not effected by this issue. + + +#### General usage + +In your Angular project: + + +``` +// without configuring providers +import { ApiModule } from 'arrayAndAnyTest'; +import { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + ApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers +import { ApiModule, Configuration, ConfigurationParameters } from 'arrayAndAnyTest'; + +export function apiConfigFactory (): Configuration { + const params: ConfigurationParameters = { + // set configuration parameters here. + } + return new Configuration(params); +} + +@NgModule({ + imports: [ ApiModule.forRoot(apiConfigFactory) ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers with an authentication service that manages your access tokens +import { ApiModule, Configuration } from 'arrayAndAnyTest'; + +@NgModule({ + imports: [ ApiModule ], + declarations: [ AppComponent ], + providers: [ + { + provide: Configuration, + useFactory: (authService: AuthService) => new Configuration( + { + basePath: environment.apiUrl, + accessToken: authService.getAccessToken.bind(authService) + } + ), + deps: [AuthService], + multi: false + } + ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +import { DefaultApi } from 'arrayAndAnyTest'; + +export class AppComponent { + constructor(private apiGateway: DefaultApi) { } +} +``` + +Note: The ApiModule is restricted to being instantiated once app wide. +This is to ensure that all services are treated as singletons. + +#### Using multiple OpenAPI files / APIs / ApiModules +In order to use multiple `ApiModules` generated from different OpenAPI 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 { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + ApiModule, + OtherApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ] +}) +export class AppModule { + +} +``` -TODO: paste example. ### Set service base path -If different than the generated base path, during app bootstrap, you can provide the base path to your service. +If different than the generated base path, during app bootstrap, you can provide the base path to your service. ``` -import { BASE_PATH } from './path-to-swagger-gen-service/index'; +import { BASE_PATH } from 'arrayAndAnyTest'; bootstrap(AppComponent, [ { provide: BASE_PATH, useValue: 'https://your-web-service.com' }, ]); -``` +``` +or + +``` +import { BASE_PATH } from 'arrayAndAnyTest'; + +@NgModule({ + imports: [], + declarations: [ AppComponent ], + providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + + +#### Using @angular/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 'arrayAndAnyTest'; +import { environment } from '../environments/environment'; + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ ], + providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api.module.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api.module.ts index ec2e7e350aa..2db45acb24e 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api.module.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api.module.ts @@ -1,21 +1,31 @@ -import { NgModule, ModuleWithProviders } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { HttpModule } from '@angular/http'; +import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core'; import { Configuration } from './configuration'; +import { HttpClient } from '@angular/common/http'; import { ProjectService } from './api/project.service'; @NgModule({ - imports: [ CommonModule, HttpModule ], + imports: [], declarations: [], exports: [], - providers: [ ProjectService ] + providers: [] }) export class ApiModule { - public static forConfig(configuration: Configuration): ModuleWithProviders { + public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders { return { ngModule: ApiModule, - providers: [ {provide: Configuration, useValue: configuration}] + providers: [ { provide: Configuration, useFactory: configurationFactory } ] + }; + } + + constructor( @Optional() @SkipSelf() parentModule: ApiModule, + @Optional() http: HttpClient) { + if (parentModule) { + throw new Error('ApiModule is already loaded. Import in your base AppModule only.'); + } + if (!http) { + throw new Error('You need to import the HttpClientModule in your AppModule! \n' + + 'See also https://github.com/angular/angular/issues/20575'); } } } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api/api.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api/api.ts index 82e8c1350d6..1ec7e5747eb 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api/api.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api/api.ts @@ -1 +1,3 @@ export * from './project.service'; +import { ProjectService } from './project.service'; +export const APIS = [ProjectService]; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api/project.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api/project.service.ts index 2a879789ec4..c6e33299a2c 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api/project.service.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api/project.service.ts @@ -1,58 +1,109 @@ /** * Cupix API - * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) * - * OpenAPI spec version: 1.7.0 + * The version of the OpenAPI document: 1.7.0 * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - -import { Inject, Injectable, Optional } from '@angular/core'; -import { Http, Headers, URLSearchParams } from '@angular/http'; -import { RequestMethod, RequestOptions, RequestOptionsArgs } from '@angular/http'; -import { Response, ResponseContentType } from '@angular/http'; - -import { Observable } from 'rxjs/Observable'; -import '../rxjs-operators'; - -import { ProjectEntity } from '../model/projectEntity'; -import { ProjectList } from '../model/projectList'; - -import { BASE_PATH } from '../variables'; -import { Configuration } from '../configuration'; - /* tslint:disable:no-unused-variable member-ordering */ +import { Inject, Injectable, Optional } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpParams, + HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + } from '@angular/common/http'; +import { CustomHttpParameterCodec } from '../encoder'; +import { Observable } from 'rxjs'; -@Injectable() +// @ts-ignore +import { ProjectEntity } from '../model/projectEntity'; +// @ts-ignore +import { ProjectList } from '../model/projectList'; + +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + + + +@Injectable({ + providedIn: 'root' +}) export class ProjectService { - protected basePath = 'https://localhost/v1'; - public defaultHeaders: Headers = new Headers(); - public configuration: Configuration = new Configuration(); - constructor(protected http: Http, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) { - if (basePath) { - this.basePath = basePath; - } + protected basePath = '/v1'; + public defaultHeaders = new HttpHeaders(); + public configuration = new Configuration(); + public encoder: HttpParameterCodec; + + constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { if (configuration) { this.configuration = configuration; - this.basePath = basePath || configuration.basePath || this.basePath; } + if (typeof this.configuration.basePath !== 'string') { + if (Array.isArray(basePath) && basePath.length > 0) { + basePath = basePath[0]; + } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; + } + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + + /** + * @param consumes string[] mime-types + * @return true: consumes contains 'multipart/form-data', false: otherwise + */ + private canConsumeForm(consumes: string[]): boolean { + const form = 'multipart/form-data'; + for (const consume of consumes) { + if (form === consume) { + return true; + } + } + return false; + } + + // @ts-ignore + private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { + if (typeof value === "object" && value instanceof Date === false) { + httpParams = this.addToHttpParamsRecursive(httpParams, value); + } else { + httpParams = this.addToHttpParamsRecursive(httpParams, value, key); + } + return httpParams; + } + + private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { + if (value == null) { + return httpParams; + } + + if (typeof value === "object") { + if (Array.isArray(value)) { + (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); + } else if (value instanceof Date) { + if (key != null) { + httpParams = httpParams.append(key, (value as Date).toISOString().substr(0, 10)); + } else { + throw Error("key may not be null if value is Date"); + } + } else { + Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( + httpParams, value[k], key != null ? `${key}.${k}` : k)); + } + } else if (key != null) { + httpParams = httpParams.append(key, value); + } else { + throw Error("key may not be null if value is not object or array"); + } + return httpParams; } /** @@ -63,233 +114,206 @@ export class ProjectService { * @param longitude * @param latitude * @param meta + * @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 createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, extraHttpRequestParams?: any): Observable { - return this.createProjectWithHttpInfo(name, address, longitude, latitude, meta, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } + public createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; + public createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { - /** - * Delete a Project - * Returns a Project JSON object - * @param id Project id - */ - public deleteProjectById(id: number, extraHttpRequestParams?: any): Observable<{}> { - return this.deleteProjectByIdWithHttpInfo(id, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Get a Project - * Returns a Project JSON object - * @param id Project id - */ - public getProjectById(id: number, extraHttpRequestParams?: any): Observable { - return this.getProjectByIdWithHttpInfo(id, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Get project list - * Returns a Project JSON object - * @param page - * @param perPage - * @param kind - * @param q - * @param filter - * @param latitude Valid with kind as location - * @param longitude Valid with kind as location - * @param scope Valid with kind as location, and between 1~9 - */ - public getProjectList(page?: number, perPage?: number, kind?: string, q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, extraHttpRequestParams?: any): Observable { - return this.getProjectListWithHttpInfo(page, perPage, kind, q, filter, latitude, longitude, scope, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Update project - * - * @param id Project id - * @param name User ID - * @param address Address - * @param longitude - * @param latitude - * @param meta - * @param thumbnail Project thumbnail - */ - public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: any, extraHttpRequestParams?: any): Observable { - return this.updateProjectWithHttpInfo(id, name, address, longitude, latitude, meta, thumbnail, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - - /** - * Create a Project - * Creates an empty Project - * @param name - * @param address - * @param longitude - * @param latitude - * @param meta - */ - public createProjectWithHttpInfo(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/projects`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - let formParams = new URLSearchParams(); + let localVarHeaders = this.defaultHeaders; + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } // to determine the Content-Type header - let consumes: string[] = [ + const consumes: string[] = [ 'application/x-www-form-urlencoded' ]; - // to determine the Accept header - let produces: string[] = [ - 'application/json' - ]; - - - headers.set('Content-Type', 'application/x-www-form-urlencoded'); + const canConsumeForm = this.canConsumeForm(consumes); + let localVarFormParams: { append(param: string, value: any): any; }; + let localVarUseForm = false; + let localVarConvertFormParamsToString = false; + if (localVarUseForm) { + localVarFormParams = new FormData(); + } else { + localVarFormParams = new HttpParams({encoder: this.encoder}); + } if (name !== undefined) { - formParams.set('name', name); + localVarFormParams = localVarFormParams.append('name', name) as any || localVarFormParams; } if (address !== undefined) { - formParams.set('address', address); + localVarFormParams = localVarFormParams.append('address', address) as any || localVarFormParams; } if (longitude !== undefined) { - formParams.set('longitude', longitude); + localVarFormParams = localVarFormParams.append('longitude', longitude) as any || localVarFormParams; } if (latitude !== undefined) { - formParams.set('latitude', latitude); + localVarFormParams = localVarFormParams.append('latitude', latitude) as any || localVarFormParams; } if (meta !== undefined) { - formParams.set('meta', meta); + localVarFormParams = localVarFormParams.append('meta', meta) as any || localVarFormParams; } - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Post, - headers: headers, - body: formParams.toString(), - search: queryParameters, - responseType: ResponseContentType.Json - }); + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } - return this.http.request(path, requestOptions); + let localVarPath = `/projects`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, + localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * Delete a Project * Returns a Project JSON object * @param id Project id + * @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 deleteProjectByIdWithHttpInfo(id: number, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/projects/${id}`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'id' is not null or undefined + public deleteProjectById(id: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; + public deleteProjectById(id: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public deleteProjectById(id: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public deleteProjectById(id: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { if (id === null || id === undefined) { throw new Error('Required parameter id was null or undefined when calling deleteProjectById.'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - 'application/json' - ]; + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } - // to determine the Accept header - let produces: string[] = [ - 'application/json' - ]; - - + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Delete, - headers: headers, - search: queryParameters, - responseType: ResponseContentType.Json - }); - - return this.http.request(path, requestOptions); + let localVarPath = `/projects/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * Get a Project * Returns a Project JSON object * @param id Project id + * @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 getProjectByIdWithHttpInfo(id: number, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/projects/${id}`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'id' is not null or undefined + public getProjectById(id: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; + public getProjectById(id: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public getProjectById(id: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public getProjectById(id: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { if (id === null || id === undefined) { throw new Error('Required parameter id was null or undefined when calling getProjectById.'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - 'application/json' - ]; + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } - // to determine the Accept header - let produces: string[] = [ - 'application/json' - ]; - - + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Get, - headers: headers, - search: queryParameters, - responseType: ResponseContentType.Json - }); - - return this.http.request(path, requestOptions); + let localVarPath = `/projects/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** @@ -303,65 +327,95 @@ export class ProjectService { * @param latitude Valid with kind as location * @param longitude Valid with kind as location * @param scope Valid with kind as location, and between 1~9 + * @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 getProjectListWithHttpInfo(page?: number, perPage?: number, kind?: string, q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/projects`; + public getProjectList(page?: number, perPage?: number, kind?: 'my_models' | 'published' | 'location', q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; + public getProjectList(page?: number, perPage?: number, kind?: 'my_models' | 'published' | 'location', q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public getProjectList(page?: number, perPage?: number, kind?: 'my_models' | 'published' | 'location', q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public getProjectList(page?: number, perPage?: number, kind?: 'my_models' | 'published' | 'location', q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - if (page !== undefined) { - queryParameters.set('page', page); + let localVarQueryParameters = new HttpParams({encoder: this.encoder}); + if (page !== undefined && page !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + page, 'page'); } - if (perPage !== undefined) { - queryParameters.set('per_page', perPage); + if (perPage !== undefined && perPage !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + perPage, 'per_page'); } - if (kind !== undefined) { - queryParameters.set('kind', kind); + if (kind !== undefined && kind !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + kind, 'kind'); } - if (q !== undefined) { - queryParameters.set('q', q); + if (q !== undefined && q !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + q, 'q'); } - if (filter !== undefined) { - queryParameters.set('filter', filter); + if (filter !== undefined && filter !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + filter, 'filter'); } - if (latitude !== undefined) { - queryParameters.set('latitude', latitude); + if (latitude !== undefined && latitude !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + latitude, 'latitude'); } - if (longitude !== undefined) { - queryParameters.set('longitude', longitude); + if (longitude !== undefined && longitude !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + longitude, 'longitude'); } - if (scope !== undefined) { - queryParameters.set('scope', scope); + if (scope !== undefined && scope !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + scope, 'scope'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); } - // to determine the Content-Type header - let consumes: string[] = [ - 'application/json' - ]; + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } - // to determine the Accept header - let produces: string[] = [ - 'application/json' - ]; - - - - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Get, - headers: headers, - search: queryParameters, - responseType: ResponseContentType.Json - }); - - return this.http.request(path, requestOptions); + let localVarPath = `/projects`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + params: localVarQueryParameters, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * Update project - * * @param id Project id * @param name User ID * @param address Address @@ -369,62 +423,97 @@ export class ProjectService { * @param latitude * @param meta * @param thumbnail Project thumbnail + * @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 updateProjectWithHttpInfo(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: any, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/projects/${id}`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - let formParams = new URLSearchParams(); - - // verify required parameter 'id' is not null or undefined + public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: Blob, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; + public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: Blob, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: Blob, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: Blob, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { if (id === null || id === undefined) { throw new Error('Required parameter id was null or undefined when calling updateProject.'); } + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } // to determine the Content-Type header - let consumes: string[] = [ + const consumes: string[] = [ 'multipart/form-data' ]; - // to determine the Accept header - let produces: string[] = [ - 'application/json' - ]; - - - headers.set('Content-Type', 'application/x-www-form-urlencoded'); + const canConsumeForm = this.canConsumeForm(consumes); + let localVarFormParams: { append(param: string, value: any): any; }; + let localVarUseForm = false; + let localVarConvertFormParamsToString = 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 + localVarUseForm = canConsumeForm; + if (localVarUseForm) { + localVarFormParams = new FormData(); + } else { + localVarFormParams = new HttpParams({encoder: this.encoder}); + } if (name !== undefined) { - formParams.set('name', name); + localVarFormParams = localVarFormParams.append('name', name) as any || localVarFormParams; } if (address !== undefined) { - formParams.set('address', address); + localVarFormParams = localVarFormParams.append('address', address) as any || localVarFormParams; } if (longitude !== undefined) { - formParams.set('longitude', longitude); + localVarFormParams = localVarFormParams.append('longitude', longitude) as any || localVarFormParams; } if (latitude !== undefined) { - formParams.set('latitude', latitude); + localVarFormParams = localVarFormParams.append('latitude', latitude) as any || localVarFormParams; } if (meta !== undefined) { - formParams.set('meta', meta); + localVarFormParams = localVarFormParams.append('meta', meta) as any || localVarFormParams; } if (thumbnail !== undefined) { - formParams.set('thumbnail', thumbnail); + localVarFormParams = localVarFormParams.append('thumbnail', thumbnail) as any || localVarFormParams; } - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Put, - headers: headers, - body: formParams.toString(), - search: queryParameters, - responseType: ResponseContentType.Json - }); + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } - return this.http.request(path, requestOptions); + let localVarPath = `/projects/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, + localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/configuration.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/configuration.ts index ec087d2b0c8..d38a4c153f2 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/configuration.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/configuration.ts @@ -1,24 +1,166 @@ +import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; + export interface ConfigurationParameters { - apiKey?: string; - username?: string; - password?: string; - accessToken?: string; - basePath?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ + encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; + /** + * The keys are the names in the securitySchemes section of the OpenAPI + * document. They should map to the value used for authentication + * minus any standard prefixes such as 'Basic' or 'Bearer'. + */ + credentials?: {[ key: string ]: string | (() => string | undefined)}; } export class Configuration { - apiKey: string; - username: string; - password: string; - accessToken: string; - basePath: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ + encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; + /** + * The keys are the names in the securitySchemes section of the OpenAPI + * document. They should map to the value used for authentication + * minus any standard prefixes such as 'Basic' or 'Bearer'. + */ + credentials: {[ key: string ]: string | (() => string | undefined)}; + constructor(configurationParameters: 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; + this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } + if (configurationParameters.credentials) { + this.credentials = configurationParameters.credentials; + } + else { + this.credentials = {}; + } + } - constructor(configurationParameters: ConfigurationParameters = {}) { - this.apiKey = configurationParameters.apiKey; - this.username = configurationParameters.username; - this.password = configurationParameters.password; - this.accessToken = configurationParameters.accessToken; - this.basePath = configurationParameters.basePath; - } + /** + * 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 undefined if no selection could be made. + */ + public selectHeaderContentType (contentTypes: string[]): string | undefined { + if (contentTypes.length === 0) { + return undefined; + } + + const type = contentTypes.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return contentTypes[0]; + } + return type; + } + + /** + * Select the correct accept content-type to use for a request. + * Uses {@link 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 undefined if no selection could be made. + */ + public selectHeaderAccept(accepts: string[]): string | undefined { + if (accepts.length === 0) { + return undefined; + } + + const type = accepts.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return accepts[0]; + } + return type; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } + + public lookupCredential(key: string): string | undefined { + const value = this.credentials[key]; + return typeof value === 'function' + ? value() + : value; + } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/encoder.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/encoder.ts new file mode 100644 index 00000000000..138c4d5cf2c --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/encoder.ts @@ -0,0 +1,20 @@ +import { HttpParameterCodec } from '@angular/common/http'; + +/** + * Custom HttpParameterCodec + * Workaround for https://github.com/angular/angular/issues/18261 + */ +export class CustomHttpParameterCodec implements HttpParameterCodec { + encodeKey(k: string): string { + return encodeURIComponent(k); + } + encodeValue(v: string): string { + return encodeURIComponent(v); + } + decodeKey(k: string): string { + return decodeURIComponent(k); + } + decodeValue(v: string): string { + return decodeURIComponent(v); + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/git_push.sh b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/git_push.sh index 484e8cc0033..67b52e22d7f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/git_push.sh +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/git_push.sh @@ -1,11 +1,17 @@ #!/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 swagger-petstore-perl "minor update" +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" git_user_id=$1 git_repo_id=$2 release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi if [ "$git_user_id" = "" ]; then git_user_id="" @@ -28,7 +34,7 @@ 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. +# Commits the tracked changes and prepares them to be pushed to a remote repository. git commit -m "$release_note" # Sets the new remote @@ -37,9 +43,9 @@ if [ "$git_remote" = "" ]; then # git remote not defined if [ "$GIT_TOKEN" = "" ]; then echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." - git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + 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}"@github.com/${git_user_id}/${git_repo_id}.git + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git fi fi @@ -47,6 +53,5 @@ fi git pull origin master # Pushes (Forces) the changes in the local repository up to the remote repository -echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" git push origin master 2>&1 | grep -v 'To https' - diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/index.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/index.ts index c312b70fa3e..104dd3d21e3 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/index.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/index.ts @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntity.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntity.ts index 76882ebe1b3..a0fc28a83a4 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntity.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntity.ts @@ -1,54 +1,34 @@ /** * Cupix API - * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) * - * OpenAPI spec version: 1.7.0 + * The version of the OpenAPI document: 1.7.0 * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - import { ProjectEntityLocation } from './projectEntityLocation'; -export interface ProjectEntity { +export interface ProjectEntity { id: number; - kind?: ProjectEntity.KindEnum; - - thumbnailUrl?: string; - + thumbnail_url?: string; name?: string; - state?: string; - - meta?: any; - + meta?: object; location?: ProjectEntityLocation; - - createdAt?: Date; - - updatedAt?: Date; - - publishedAt?: Date; - + created_at?: string; + updated_at?: string; + published_at?: string; } export namespace ProjectEntity { - export enum KindEnum { - Project = 'project' - } + export type KindEnum = 'project'; + export const KindEnum = { + Project: 'project' as KindEnum + }; } + + diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntityLocation.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntityLocation.ts index 1f84395dae2..30c1aaefd5e 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntityLocation.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntityLocation.ts @@ -1,32 +1,18 @@ /** * Cupix API - * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) * - * OpenAPI spec version: 1.7.0 + * The version of the OpenAPI document: 1.7.0 * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - -export interface ProjectEntityLocation { +export interface ProjectEntityLocation { lat?: number; - lon?: number; - } + diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectList.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectList.ts index c5bdf4283bb..7801e2f203c 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectList.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectList.ts @@ -1,31 +1,18 @@ /** * Cupix API - * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) * - * OpenAPI spec version: 1.7.0 + * The version of the OpenAPI document: 1.7.0 * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - import { ProjectEntity } from './projectEntity'; -export interface ProjectList { +export interface ProjectList { contents: Array; - } + diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/ng-package.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/ng-package.json new file mode 100644 index 00000000000..3b17900dc9c --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/ng-package.json @@ -0,0 +1,6 @@ +{ + "$schema": "./node_modules/ng-packagr/ng-package.schema.json", + "lib": { + "entryFile": "index.ts" + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/package.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/package.json index 16a813c383c..f813e8e5f7a 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/package.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/package.json @@ -1,38 +1,34 @@ { "name": "arrayAndAnyTest", "version": "1.0.2", - "description": "swagger client for arrayAndAnyTest", - "author": "Swagger Codegen Contributors", + "description": "OpenAPI client for arrayAndAnyTest", + "author": "OpenAPI-Generator Contributors", + "repository": { + "type": "git", + "url": "https:////.git" + }, "keywords": [ - "swagger-client" + "openapi-client", + "openapi-generator" ], - "license": "Apache-2.0", - "main": "dist/index.js", - "typings": "dist/index.d.ts", + "license": "Unlicense", "scripts": { - "build": "typings install && tsc --outDir dist/" + "build": "ng-packagr -p ng-package.json" }, "peerDependencies": { - "@angular/core": "^2.0.0", - "@angular/http": "^2.0.0", - "@angular/common": "^2.0.0", - "@angular/compiler": "^2.0.0", - "core-js": "^2.4.0", - "reflect-metadata": "^0.1.3", - "rxjs": "5.0.0-beta.12", - "zone.js": "^0.6.17" + "@angular/core": "^14.0.5", + "rxjs": "^7.5.5" }, "devDependencies": { - "@angular/core": "^2.0.0", - "@angular/http": "^2.0.0", - "@angular/common": "^2.0.0", - "@angular/compiler": "^2.0.0", - "@angular/platform-browser": "^2.0.0", - "core-js": "^2.4.0", + "@angular/common": "^14.0.5", + "@angular/compiler": "^14.0.5", + "@angular/compiler-cli": "^14.0.5", + "@angular/core": "^14.0.5", + "@angular/platform-browser": "^14.0.5", + "ng-packagr": "^14.0.2", "reflect-metadata": "^0.1.3", - "rxjs": "5.0.0-beta.12", - "zone.js": "^0.6.17", - "typescript": "^4.0", - "typings": "^1.3.2" - } -} + "rxjs": "^7.5.5", + "tsickle": "^0.46.3", + "typescript": ">=4.6.0 <=4.8.0", + "zone.js": "^0.11.5" + }} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/param.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/rxjs-operators.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/rxjs-operators.ts deleted file mode 100644 index 5659cd0694f..00000000000 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/rxjs-operators.ts +++ /dev/null @@ -1,11 +0,0 @@ -// RxJS imports according to https://angular.io/docs/ts/latest/guide/server-communication.html#!#rxjs - -// See node_module/rxjs/Rxjs.js -// Import just the rxjs statics and operators we need for THIS app. - -// Statics -import 'rxjs/add/observable/throw'; - -// Operators -import 'rxjs/add/operator/catch'; -import 'rxjs/add/operator/map'; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/tsconfig.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/tsconfig.json index e1f949692b6..c01ebe255d4 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/tsconfig.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/tsconfig.json @@ -1,28 +1,28 @@ { - "compilerOptions": { - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "noImplicitAny": false, - "suppressImplicitAnyIndexErrors": true, - "target": "es5", - "module": "commonjs", - "moduleResolution": "node", - "removeComments": true, - "sourceMap": true, - "outDir": "./lib", - "noLib": false, - "declaration": true - }, - "exclude": [ - "node_modules", - "typings/main.d.ts", - "typings/main", - "lib", - "dist" - ], - "filesGlob": [ - "./model/*.ts", - "./api/*.ts", - "typings/browser.d.ts" - ] + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "noImplicitAny": false, + "suppressImplicitAnyIndexErrors": true, + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "removeComments": true, + "sourceMap": true, + "outDir": "./dist", + "noLib": false, + "declaration": true, + "lib": [ "es6", "dom" ], + "typeRoots": [ + "node_modules/@types" + ] + }, + "exclude": [ + "node_modules", + "dist" + ], + "filesGlob": [ + "./model/*.ts", + "./api/*.ts" + ] } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/typings.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/typings.json deleted file mode 100644 index 507c40e5cbe..00000000000 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/typings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "globalDependencies": { - "core-js": "registry:dt/core-js#0.0.0+20160725163759" - } -} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/variables.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/variables.ts index 27b987e9b23..6fe58549f39 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/variables.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/variables.ts @@ -1,3 +1,9 @@ -import { OpaqueToken } from '@angular/core'; +import { InjectionToken } from '@angular/core'; -export const BASE_PATH = new OpaqueToken('basePath'); \ No newline at end of file +export const BASE_PATH = new InjectionToken('basePath'); +export const COLLECTION_FORMATS = { + 'csv': ',', + 'tsv': ' ', + 'ssv': ' ', + 'pipes': '|' +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/.gitignore b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/.gitignore new file mode 100644 index 00000000000..149b5765472 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/.gitignore @@ -0,0 +1,4 @@ +wwwroot/*.js +node_modules +typings +dist diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/README.md b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/README.md new file mode 100644 index 00000000000..3dbfaf6cd40 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/README.md @@ -0,0 +1,226 @@ +## custom-path-params-integration-test@1.0.3 + +### Building + +To install the required dependencies and to build the typescript sources run: +``` +npm install +npm run build +``` + +### publishing + +First build the package then run ```npm publish dist``` (don't forget to specify the `dist` folder!) + +### consuming + +Navigate to the folder of your consuming project and run one of next commands. + +_published:_ + +``` +npm install custom-path-params-integration-test@1.0.3 --save +``` + +_without publishing (not recommended):_ + +``` +npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save +``` + +_It's important to take the tgz file, otherwise you'll get trouble with links on windows_ + +_using `npm link`:_ + +In PATH_TO_GENERATED_PACKAGE/dist: +``` +npm link +``` + +In your project: +``` +npm link custom-path-params-integration-test +``` + +__Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. +Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Published packages are not effected by this issue. + + +#### General usage + +In your Angular project: + + +``` +// without configuring providers +import { ApiModule } from 'custom-path-params-integration-test'; +import { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + ApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers +import { ApiModule, Configuration, ConfigurationParameters } from 'custom-path-params-integration-test'; + +export function apiConfigFactory (): Configuration { + const params: ConfigurationParameters = { + // set configuration parameters here. + } + return new Configuration(params); +} + +@NgModule({ + imports: [ ApiModule.forRoot(apiConfigFactory) ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers with an authentication service that manages your access tokens +import { ApiModule, Configuration } from 'custom-path-params-integration-test'; + +@NgModule({ + imports: [ ApiModule ], + declarations: [ AppComponent ], + providers: [ + { + provide: Configuration, + useFactory: (authService: AuthService) => new Configuration( + { + basePath: environment.apiUrl, + accessToken: authService.getAccessToken.bind(authService) + } + ), + deps: [AuthService], + multi: false + } + ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +import { DefaultApi } from 'custom-path-params-integration-test'; + +export class AppComponent { + constructor(private apiGateway: DefaultApi) { } +} +``` + +Note: The ApiModule is restricted to being instantiated once app wide. +This is to ensure that all services are treated as singletons. + +#### Using multiple OpenAPI files / APIs / ApiModules +In order to use multiple `ApiModules` generated from different OpenAPI 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 { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + ApiModule, + OtherApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ] +}) +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 'custom-path-params-integration-test'; + +bootstrap(AppComponent, [ + { provide: BASE_PATH, useValue: 'https://your-web-service.com' }, +]); +``` +or + +``` +import { BASE_PATH } from 'custom-path-params-integration-test'; + +@NgModule({ + imports: [], + declarations: [ AppComponent ], + providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + + +#### Using @angular/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 'custom-path-params-integration-test'; +import { environment } from '../environments/environment'; + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ ], + providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api.module.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api.module.ts new file mode 100644 index 00000000000..5dcf060157a --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api.module.ts @@ -0,0 +1,31 @@ +import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core'; +import { Configuration } from './configuration'; +import { HttpClient } from '@angular/common/http'; + +import { MatrixParamsService } from './api/matrixParams.service'; + +@NgModule({ + imports: [], + declarations: [], + exports: [], + providers: [] +}) +export class ApiModule { + public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders { + return { + ngModule: ApiModule, + providers: [ { provide: Configuration, useFactory: configurationFactory } ] + }; + } + + constructor( @Optional() @SkipSelf() parentModule: ApiModule, + @Optional() http: HttpClient) { + if (parentModule) { + throw new Error('ApiModule is already loaded. Import in your base AppModule only.'); + } + if (!http) { + throw new Error('You need to import the HttpClientModule in your AppModule! \n' + + 'See also https://github.com/angular/angular/issues/20575'); + } + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api/api.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api/api.ts new file mode 100644 index 00000000000..b6cf2e7c9cd --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api/api.ts @@ -0,0 +1,3 @@ +export * from './matrixParams.service'; +import { MatrixParamsService } from './matrixParams.service'; +export const APIS = [MatrixParamsService]; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api/matrixParams.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api/matrixParams.service.ts new file mode 100644 index 00000000000..099eb554e1f --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api/matrixParams.service.ts @@ -0,0 +1,310 @@ +/** + * Path Parameter Stuff + * This API shows the usage of various path parameter styles + * + * 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 { Inject, Injectable, Optional } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpParams, + HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + } from '@angular/common/http'; +import { CustomHttpParameterCodec } from '../encoder'; +import { Observable } from 'rxjs'; + +// @ts-ignore +import { ComplexParams } from '../model/complexParams'; + +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + + + +@Injectable({ + providedIn: 'root' +}) +export class MatrixParamsService { + + protected basePath = 'http://localhost'; + public defaultHeaders = new HttpHeaders(); + public configuration = new Configuration(); + public encoder: HttpParameterCodec; + + constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { + if (configuration) { + this.configuration = configuration; + } + if (typeof this.configuration.basePath !== 'string') { + if (Array.isArray(basePath) && basePath.length > 0) { + basePath = basePath[0]; + } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; + } + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + + + // @ts-ignore + private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { + if (typeof value === "object" && value instanceof Date === false) { + httpParams = this.addToHttpParamsRecursive(httpParams, value); + } else { + httpParams = this.addToHttpParamsRecursive(httpParams, value, key); + } + return httpParams; + } + + private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { + if (value == null) { + return httpParams; + } + + if (typeof value === "object") { + if (Array.isArray(value)) { + (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); + } else if (value instanceof Date) { + if (key != null) { + httpParams = httpParams.append(key, (value as Date).toISOString().substr(0, 10)); + } else { + throw Error("key may not be null if value is Date"); + } + } else { + Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( + httpParams, value[k], key != null ? `${key}.${k}` : k)); + } + } else if (key != null) { + httpParams = httpParams.append(key, value); + } else { + throw Error("key may not be null if value is not object or array"); + } + return httpParams; + } + + /** + * @param matrixParamExploded + * @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 complexMatrixParamExploded(matrixParamExploded?: ComplexParams, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public complexMatrixParamExploded(matrixParamExploded?: ComplexParams, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public complexMatrixParamExploded(matrixParamExploded?: ComplexParams, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public complexMatrixParamExploded(matrixParamExploded?: ComplexParams, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/complexMatrixParamExploded${this.configuration.encodeParam({name: "matrixParamExploded", value: matrixParamExploded, in: "path", style: "matrix", explode: true, dataType: "ComplexParams", dataFormat: undefined})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, + null, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * @param matrixParamFlat + * @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 complexMatrixParamFlat(matrixParamFlat?: ComplexParams, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public complexMatrixParamFlat(matrixParamFlat?: ComplexParams, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public complexMatrixParamFlat(matrixParamFlat?: ComplexParams, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public complexMatrixParamFlat(matrixParamFlat?: ComplexParams, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/complexMatrixParamFlat${this.configuration.encodeParam({name: "matrixParamFlat", value: matrixParamFlat, in: "path", style: "matrix", explode: false, dataType: "ComplexParams", dataFormat: undefined})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, + null, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * @param plainParamFlat + * @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 plainMatrixParamFlat(plainParamFlat?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public plainMatrixParamFlat(plainParamFlat?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public plainMatrixParamFlat(plainParamFlat?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public plainMatrixParamFlat(plainParamFlat?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/plainMatrixParamFlat${this.configuration.encodeParam({name: "plainParamFlat", value: plainParamFlat, in: "path", style: "matrix", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, + null, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + + /** + * @param dateTimeParamFlat + * @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 plainMatrixParamFlat_1(dateTimeParamFlat?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public plainMatrixParamFlat_1(dateTimeParamFlat?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public plainMatrixParamFlat_1(dateTimeParamFlat?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public plainMatrixParamFlat_1(dateTimeParamFlat?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/date-timeMatrixParamFlat${this.configuration.encodeParam({name: "dateTimeParamFlat", value: dateTimeParamFlat, in: "path", style: "matrix", explode: false, dataType: "string", dataFormat: "date-time"})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, + null, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/configuration.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/configuration.ts new file mode 100644 index 00000000000..d38a4c153f2 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/configuration.ts @@ -0,0 +1,166 @@ +import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; + +export interface ConfigurationParameters { + /** + * @deprecated Since 5.0. Use credentials instead + */ + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ + encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; + /** + * The keys are the names in the securitySchemes section of the OpenAPI + * document. They should map to the value used for authentication + * minus any standard prefixes such as 'Basic' or 'Bearer'. + */ + credentials?: {[ key: string ]: string | (() => string | undefined)}; +} + +export class Configuration { + /** + * @deprecated Since 5.0. Use credentials instead + */ + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ + encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; + /** + * The keys are the names in the securitySchemes section of the OpenAPI + * document. They should map to the value used for authentication + * minus any standard prefixes such as 'Basic' or 'Bearer'. + */ + credentials: {[ key: string ]: string | (() => string | undefined)}; + + constructor(configurationParameters: 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; + this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } + if (configurationParameters.credentials) { + this.credentials = configurationParameters.credentials; + } + else { + this.credentials = {}; + } + } + + /** + * 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 undefined if no selection could be made. + */ + public selectHeaderContentType (contentTypes: string[]): string | undefined { + if (contentTypes.length === 0) { + return undefined; + } + + const type = contentTypes.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return contentTypes[0]; + } + return type; + } + + /** + * Select the correct accept content-type to use for a request. + * Uses {@link 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 undefined if no selection could be made. + */ + public selectHeaderAccept(accepts: string[]): string | undefined { + if (accepts.length === 0) { + return undefined; + } + + const type = accepts.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return accepts[0]; + } + return type; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } + + public lookupCredential(key: string): string | undefined { + const value = this.credentials[key]; + return typeof value === 'function' + ? value() + : value; + } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/encoder.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/encoder.ts new file mode 100644 index 00000000000..138c4d5cf2c --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/encoder.ts @@ -0,0 +1,20 @@ +import { HttpParameterCodec } from '@angular/common/http'; + +/** + * Custom HttpParameterCodec + * Workaround for https://github.com/angular/angular/issues/18261 + */ +export class CustomHttpParameterCodec implements HttpParameterCodec { + encodeKey(k: string): string { + return encodeURIComponent(k); + } + encodeValue(v: string): string { + return encodeURIComponent(v); + } + decodeKey(k: string): string { + return decodeURIComponent(k); + } + decodeValue(v: string): string { + return decodeURIComponent(v); + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/git_push.sh b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/git_push.sh new file mode 100644 index 00000000000..67b52e22d7f --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/git_push.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + 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="" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="" + 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' diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/index.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/index.ts new file mode 100644 index 00000000000..104dd3d21e3 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/index.ts @@ -0,0 +1,6 @@ +export * from './api/api'; +export * from './model/models'; +export * from './variables'; +export * from './configuration'; +export * from './api.module'; +export * from './param'; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/model/complexParams.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/model/complexParams.ts new file mode 100644 index 00000000000..bed1db7a6ee --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/model/complexParams.ts @@ -0,0 +1,18 @@ +/** + * Path Parameter Stuff + * This API shows the usage of various path parameter styles + * + * 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. + */ + + +export interface ComplexParams { + key?: string; + value?: number; +} + diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/model/models.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/model/models.ts new file mode 100644 index 00000000000..329693285d0 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/model/models.ts @@ -0,0 +1 @@ +export * from './complexParams'; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/ng-package.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/ng-package.json new file mode 100644 index 00000000000..3b17900dc9c --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/ng-package.json @@ -0,0 +1,6 @@ +{ + "$schema": "./node_modules/ng-packagr/ng-package.schema.json", + "lib": { + "entryFile": "index.ts" + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/package.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/package.json new file mode 100644 index 00000000000..c68cbf4ebe2 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/package.json @@ -0,0 +1,34 @@ +{ + "name": "custom-path-params-integration-test", + "version": "1.0.3", + "description": "OpenAPI client for custom-path-params-integration-test", + "author": "OpenAPI-Generator Contributors", + "repository": { + "type": "git", + "url": "https:////.git" + }, + "keywords": [ + "openapi-client", + "openapi-generator" + ], + "license": "Unlicense", + "scripts": { + "build": "ng-packagr -p ng-package.json" + }, + "peerDependencies": { + "@angular/core": "^14.0.5", + "rxjs": "^7.5.5" + }, + "devDependencies": { + "@angular/common": "^14.0.5", + "@angular/compiler": "^14.0.5", + "@angular/compiler-cli": "^14.0.5", + "@angular/core": "^14.0.5", + "@angular/platform-browser": "^14.0.5", + "ng-packagr": "^14.0.2", + "reflect-metadata": "^0.1.3", + "rxjs": "^7.5.5", + "tsickle": "^0.46.3", + "typescript": ">=4.6.0 <=4.8.0", + "zone.js": "^0.11.5" + }} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/param.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/tsconfig.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/tsconfig.json new file mode 100644 index 00000000000..c01ebe255d4 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "noImplicitAny": false, + "suppressImplicitAnyIndexErrors": true, + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "removeComments": true, + "sourceMap": true, + "outDir": "./dist", + "noLib": false, + "declaration": true, + "lib": [ "es6", "dom" ], + "typeRoots": [ + "node_modules/@types" + ] + }, + "exclude": [ + "node_modules", + "dist" + ], + "filesGlob": [ + "./model/*.ts", + "./api/*.ts" + ] +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/variables.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/variables.ts new file mode 100644 index 00000000000..6fe58549f39 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/variables.ts @@ -0,0 +1,9 @@ +import { InjectionToken } from '@angular/core'; + +export const BASE_PATH = new InjectionToken('basePath'); +export const COLLECTION_FORMATS = { + 'csv': ',', + 'tsv': ' ', + 'ssv': ' ', + 'pipes': '|' +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-spec.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-spec.json new file mode 100644 index 00000000000..f758f4c3c39 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-spec.json @@ -0,0 +1,129 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Path Parameter Stuff", + "description": "This API shows the usage of various path parameter styles", + "version": "1.0.0" + }, + "paths": { + "/complexMatrixParamExploded{matrixParamExploded}": { + "parameters": [ + { + "name": "matrixParamExploded", + "in": "path", + "style": "matrix", + "explode": true, + "required": false, + "schema": { + "$ref": "#/components/schemas/ComplexParams" + } + } + ], + "put": { + "tags": [ + "MatrixParams" + ], + "operationId": "complexMatrixParamExploded", + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/complexMatrixParamFlat{matrixParamFlat}": { + "parameters": [ + { + "name": "matrixParamFlat", + "in": "path", + "style": "matrix", + "explode": false, + "required": false, + "schema": { + "$ref": "#/components/schemas/ComplexParams" + } + } + ], + "put": { + "tags": [ + "MatrixParams" + ], + "operationId": "complexMatrixParamFlat", + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/plainMatrixParamFlat{plainParamFlat}": { + "parameters": [ + { + "name": "plainParamFlat", + "in": "path", + "style": "matrix", + "explode": false, + "required": false, + "schema": { + "$ref": "#/components/schemas/PlainParam" + } + } + ], + "put": { + "tags": [ + "MatrixParams" + ], + "operationId": "plainMatrixParamFlat", + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/date-timeMatrixParamFlat{dateTimeParamFlat}": { + "parameters": [ + { + "name": "dateTimeParamFlat", + "in": "path", + "style": "matrix", + "explode": false, + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "put": { + "tags": [ + "MatrixParams" + ], + "operationId": "plainMatrixParamFlat", + "responses": { + "200": { + "description": "OK" + } + } + } + } + }, + "components": { + "schemas": { + "PlainParam": { + "type": "string" + }, + "ComplexParams": { + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "number", + "format": "int64" + } + } + } + } + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/.gitignore b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/.gitignore index 35e2fb2b02e..149b5765472 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/.gitignore +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/.gitignore @@ -1,3 +1,4 @@ wwwroot/*.js node_modules typings +dist diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/.openapi-generator-ignore b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/.openapi-generator-ignore deleted file mode 100644 index deed424f8a1..00000000000 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/.openapi-generator-ignore +++ /dev/null @@ -1,23 +0,0 @@ -# Swagger Codegen Ignore -# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen - -# 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 Swagger Codegen 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 diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/LICENSE b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/LICENSE deleted file mode 100644 index 3f4d322ebd7..00000000000 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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. diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/README.md b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/README.md index 25b7aaaf39a..5865977635e 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/README.md +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/README.md @@ -2,7 +2,7 @@ ### Building -To build and compile the typescript sources to javascript use: +To install the required dependencies and to build the typescript sources run: ``` npm install npm run build @@ -10,11 +10,11 @@ npm run build ### publishing -First build the package than run ```npm publish``` +First build the package then run ```npm publish dist``` (don't forget to specify the `dist` folder!) ### consuming -navigate to the folder of your consuming project and run one of next commando's. +Navigate to the folder of your consuming project and run one of next commands. _published:_ @@ -22,23 +22,205 @@ _published:_ npm install petstore-integration-test@1.0.3 --save ``` -_unPublished (not recommended):_ +_without publishing (not recommended):_ ``` -npm install PATH_TO_GENERATED_PACKAGE --save +npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save ``` -In your angular2 project: +_It's important to take the tgz file, otherwise you'll get trouble with links on windows_ + +_using `npm link`:_ + +In PATH_TO_GENERATED_PACKAGE/dist: +``` +npm link +``` + +In your project: +``` +npm link petstore-integration-test +``` + +__Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. +Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Published packages are not effected by this issue. + + +#### General usage + +In your Angular project: + + +``` +// without configuring providers +import { ApiModule } from 'petstore-integration-test'; +import { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + ApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers +import { ApiModule, Configuration, ConfigurationParameters } from 'petstore-integration-test'; + +export function apiConfigFactory (): Configuration { + const params: ConfigurationParameters = { + // set configuration parameters here. + } + return new Configuration(params); +} + +@NgModule({ + imports: [ ApiModule.forRoot(apiConfigFactory) ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers with an authentication service that manages your access tokens +import { ApiModule, Configuration } from 'petstore-integration-test'; + +@NgModule({ + imports: [ ApiModule ], + declarations: [ AppComponent ], + providers: [ + { + provide: Configuration, + useFactory: (authService: AuthService) => new Configuration( + { + basePath: environment.apiUrl, + accessToken: authService.getAccessToken.bind(authService) + } + ), + deps: [AuthService], + multi: false + } + ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +import { DefaultApi } from 'petstore-integration-test'; + +export class AppComponent { + constructor(private apiGateway: DefaultApi) { } +} +``` + +Note: The ApiModule is restricted to being instantiated once app wide. +This is to ensure that all services are treated as singletons. + +#### Using multiple OpenAPI files / APIs / ApiModules +In order to use multiple `ApiModules` generated from different OpenAPI 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 { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + ApiModule, + OtherApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ] +}) +export class AppModule { + +} +``` -TODO: paste example. ### Set service base path -If different than the generated base path, during app bootstrap, you can provide the base path to your service. +If different than the generated base path, during app bootstrap, you can provide the base path to your service. ``` -import { BASE_PATH } from './path-to-swagger-gen-service/index'; +import { BASE_PATH } from 'petstore-integration-test'; bootstrap(AppComponent, [ { provide: BASE_PATH, useValue: 'https://your-web-service.com' }, ]); -``` +``` +or + +``` +import { BASE_PATH } from 'petstore-integration-test'; + +@NgModule({ + imports: [], + declarations: [ AppComponent ], + providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + + +#### Using @angular/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 'petstore-integration-test'; +import { environment } from '../environments/environment'; + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ ], + providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api.module.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api.module.ts index 4a2ae9c2e9f..2afb8f64e92 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api.module.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api.module.ts @@ -1,23 +1,33 @@ -import { NgModule, ModuleWithProviders } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { HttpModule } from '@angular/http'; +import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core'; import { Configuration } from './configuration'; +import { HttpClient } from '@angular/common/http'; import { PetService } from './api/pet.service'; import { StoreService } from './api/store.service'; import { UserService } from './api/user.service'; @NgModule({ - imports: [ CommonModule, HttpModule ], + imports: [], declarations: [], exports: [], - providers: [ PetService, StoreService, UserService ] + providers: [] }) export class ApiModule { - public static forConfig(configuration: Configuration): ModuleWithProviders { + public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders { return { ngModule: ApiModule, - providers: [ {provide: Configuration, useValue: configuration}] + providers: [ { provide: Configuration, useFactory: configurationFactory } ] + }; + } + + constructor( @Optional() @SkipSelf() parentModule: ApiModule, + @Optional() http: HttpClient) { + if (parentModule) { + throw new Error('ApiModule is already loaded. Import in your base AppModule only.'); + } + if (!http) { + throw new Error('You need to import the HttpClientModule in your AppModule! \n' + + 'See also https://github.com/angular/angular/issues/20575'); } } } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/api.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/api.ts index b7d674969f5..8e44b64083d 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/api.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/api.ts @@ -1,3 +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]; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/pet.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/pet.service.ts index a1517db0e3d..a6d4153dc9f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/pet.service.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/pet.service.ts @@ -1,646 +1,724 @@ /** - * Swagger Petstore - * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * 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. * - * OpenAPI spec version: 1.0.0 - * Contact: apiteam@swagger.io + * The version of the OpenAPI document: 1.0.0 + * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - -import { Inject, Injectable, Optional } from '@angular/core'; -import { Http, Headers, URLSearchParams } from '@angular/http'; -import { RequestMethod, RequestOptions, RequestOptionsArgs } from '@angular/http'; -import { Response, ResponseContentType } from '@angular/http'; - -import { Observable } from 'rxjs/Observable'; -import '../rxjs-operators'; - -import { Pet } from '../model/pet'; -import { ApiResponse } from '../model/apiResponse'; - -import { BASE_PATH } from '../variables'; -import { Configuration } from '../configuration'; - /* tslint:disable:no-unused-variable member-ordering */ +import { Inject, Injectable, Optional } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpParams, + HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + } from '@angular/common/http'; +import { CustomHttpParameterCodec } from '../encoder'; +import { Observable } from 'rxjs'; -@Injectable() +// @ts-ignore +import { ApiResponse } from '../model/apiResponse'; +// @ts-ignore +import { Pet } from '../model/pet'; + +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + + + +@Injectable({ + providedIn: 'root' +}) export class PetService { - protected basePath = 'http://petstore.swagger.io/v2'; - public defaultHeaders: Headers = new Headers(); - public configuration: Configuration = new Configuration(); - constructor(protected http: Http, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) { - if (basePath) { - this.basePath = basePath; - } + protected basePath = 'http://petstore.swagger.io/v2'; + public defaultHeaders = new HttpHeaders(); + public configuration = new Configuration(); + public encoder: HttpParameterCodec; + + constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { if (configuration) { this.configuration = configuration; - this.basePath = basePath || configuration.basePath || this.basePath; } + if (typeof this.configuration.basePath !== 'string') { + if (Array.isArray(basePath) && basePath.length > 0) { + basePath = basePath[0]; + } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; + } + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); } - - /** - * - * Extends object by coping non-existing properties. - * @param objA object to be extended - * @param objB source object + + /** + * @param consumes string[] mime-types + * @return true: consumes contains 'multipart/form-data', false: otherwise */ - private extendObj(objA: T1, objB: T2) { - for(let key in objB){ - if(objB.hasOwnProperty(key)){ - objA[key] = objB[key]; + private canConsumeForm(consumes: string[]): boolean { + const form = 'multipart/form-data'; + for (const consume of consumes) { + if (form === consume) { + return true; } } - return objA; + return false; + } + + // @ts-ignore + private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { + if (typeof value === "object" && value instanceof Date === false) { + httpParams = this.addToHttpParamsRecursive(httpParams, value); + } else { + httpParams = this.addToHttpParamsRecursive(httpParams, value, key); + } + return httpParams; + } + + private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { + if (value == null) { + return httpParams; + } + + if (typeof value === "object") { + if (Array.isArray(value)) { + (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); + } else if (value instanceof Date) { + if (key != null) { + httpParams = httpParams.append(key, (value as Date).toISOString().substr(0, 10)); + } else { + throw Error("key may not be null if value is Date"); + } + } else { + Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( + httpParams, value[k], key != null ? `${key}.${k}` : k)); + } + } else if (key != null) { + httpParams = httpParams.append(key, value); + } else { + throw Error("key may not be null if value is not object or array"); + } + return httpParams; } /** * Add a new pet to the store - * * @param body 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(body: Pet, extraHttpRequestParams?: any): Observable<{}> { - return this.addPetWithHttpInfo(body, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Deletes a pet - * - * @param petId Pet id to delete - * @param apiKey - */ - public deletePet(petId: number, apiKey?: string, extraHttpRequestParams?: any): Observable<{}> { - return this.deletePetWithHttpInfo(petId, apiKey, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * 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 - */ - public findPetsByStatus(status: Array, extraHttpRequestParams?: any): Observable> { - return this.findPetsByStatusWithHttpInfo(status, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * 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 - */ - public findPetsByTags(tags: Array, extraHttpRequestParams?: any): Observable> { - return this.findPetsByTagsWithHttpInfo(tags, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Find pet by ID - * Returns a single pet - * @param petId ID of pet to return - */ - public getPetById(petId: number, extraHttpRequestParams?: any): Observable { - return this.getPetByIdWithHttpInfo(petId, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Update an existing pet - * - * @param body Pet object that needs to be added to the store - */ - public updatePet(body: Pet, extraHttpRequestParams?: any): Observable<{}> { - return this.updatePetWithHttpInfo(body, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * 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 - */ - public updatePetWithForm(petId: number, name?: string, status?: string, extraHttpRequestParams?: any): Observable<{}> { - return this.updatePetWithFormWithHttpInfo(petId, name, status, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * uploads an image - * - * @param petId ID of pet to update - * @param additionalMetadata Additional data to pass to server - * @param file file to upload - */ - public uploadFile(petId: number, additionalMetadata?: string, file?: any, extraHttpRequestParams?: any): Observable { - return this.uploadFileWithHttpInfo(petId, additionalMetadata, file, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - - /** - * Add a new pet to the store - * - * @param body Pet object that needs to be added to the store - */ - public addPetWithHttpInfo(body: Pet, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/pet`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'body' is not null or undefined + public addPet(body: Pet, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public addPet(body: Pet, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public addPet(body: Pet, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public addPet(body: Pet, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling addPet.'); } + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (petstore_auth) required + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + // to determine the Content-Type header - let consumes: string[] = [ - 'application/json', + const consumes: string[] = [ + 'application/json', 'application/xml' ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - // authentication (petstore_auth) required - // oauth required - if (this.configuration.accessToken) - { - headers.set('Authorization', 'Bearer ' + this.configuration.accessToken); - } - - - headers.set('Content-Type', 'application/json'); - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Post, - headers: headers, - body: body == null ? '' : JSON.stringify(body), // https://github.com/angular/angular/issues/10612 - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); } - return this.http.request(path, requestOptions); + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, + body, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * 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 deletePetWithHttpInfo(petId: number, apiKey?: string, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/pet/${petId}`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'petId' is not null or undefined + public deletePet(petId: number, apiKey?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public deletePet(petId: number, apiKey?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public deletePet(petId: number, apiKey?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public deletePet(petId: number, apiKey?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { if (petId === null || petId === undefined) { throw new Error('Required parameter petId was null or undefined when calling deletePet.'); } + let localVarHeaders = this.defaultHeaders; + if (apiKey !== undefined && apiKey !== null) { + localVarHeaders = localVarHeaders.set('api_key', String(apiKey)); + } - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - + let localVarCredential: string | undefined; // authentication (petstore_auth) required - // oauth required - if (this.configuration.accessToken) - { - headers.set('Authorization', 'Bearer ' + this.configuration.accessToken); - } - - - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Delete, - headers: headers, - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); } - return this.http.request(path, requestOptions); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * 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 findPetsByStatusWithHttpInfo(status: Array, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/pet/findByStatus`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'status' is not null or undefined + public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>>; + public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>>; + public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { if (status === null || status === undefined) { throw new Error('Required parameter status was null or undefined when calling findPetsByStatus.'); } - if (status !== undefined) { - queryParameters.set('status', status); + + let localVarQueryParameters = new HttpParams({encoder: this.encoder}); + if (status) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + status.join(COLLECTION_FORMATS['csv']), 'status'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - + let localVarCredential: string | undefined; // authentication (petstore_auth) required - // oauth required - if (this.configuration.accessToken) - { - headers.set('Authorization', 'Bearer ' + this.configuration.accessToken); - } - - - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Get, - headers: headers, - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); } - return this.http.request(path, requestOptions); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet/findByStatus`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + params: localVarQueryParameters, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * 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 findPetsByTagsWithHttpInfo(tags: Array, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/pet/findByTags`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'tags' is not null or undefined + public findPetsByTags(tags: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public findPetsByTags(tags: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>>; + public findPetsByTags(tags: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>>; + public findPetsByTags(tags: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { if (tags === null || tags === undefined) { throw new Error('Required parameter tags was null or undefined when calling findPetsByTags.'); } - if (tags !== undefined) { - queryParameters.set('tags', tags); + + let localVarQueryParameters = new HttpParams({encoder: this.encoder}); + if (tags) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + tags.join(COLLECTION_FORMATS['csv']), 'tags'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - + let localVarCredential: string | undefined; // authentication (petstore_auth) required - // oauth required - if (this.configuration.accessToken) - { - headers.set('Authorization', 'Bearer ' + this.configuration.accessToken); - } - - - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Get, - headers: headers, - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); } - return this.http.request(path, requestOptions); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet/findByTags`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + params: localVarQueryParameters, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * 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 getPetByIdWithHttpInfo(petId: number, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/pet/${petId}`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'petId' is not null or undefined + public getPetById(petId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; + public getPetById(petId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public getPetById(petId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public getPetById(petId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { if (petId === null || petId === undefined) { throw new Error('Required parameter petId was null or undefined when calling getPetById.'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - + let localVarCredential: string | undefined; // authentication (api_key) required - if (this.configuration.apiKey) - { - headers.set('api_key', this.configuration.apiKey); - } - - - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Get, - headers: headers, - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + localVarCredential = this.configuration.lookupCredential('api_key'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('api_key', localVarCredential); } - return this.http.request(path, requestOptions); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * Update an existing pet - * * @param body 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 updatePetWithHttpInfo(body: Pet, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/pet`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'body' is not null or undefined + public updatePet(body: Pet, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public updatePet(body: Pet, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public updatePet(body: Pet, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public updatePet(body: Pet, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling updatePet.'); } + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (petstore_auth) required + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + // to determine the Content-Type header - let consumes: string[] = [ - 'application/json', + const consumes: string[] = [ + 'application/json', 'application/xml' ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - // authentication (petstore_auth) required - // oauth required - if (this.configuration.accessToken) - { - headers.set('Authorization', 'Bearer ' + this.configuration.accessToken); - } - - - headers.set('Content-Type', 'application/json'); - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Put, - headers: headers, - body: body == null ? '' : JSON.stringify(body), // https://github.com/angular/angular/issues/10612 - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); } - return this.http.request(path, requestOptions); + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/pet`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, + body, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * 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 updatePetWithFormWithHttpInfo(petId: number, name?: string, status?: string, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/pet/${petId}`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - let formParams = new URLSearchParams(); - - // verify required parameter 'petId' is not null or undefined + public updatePetWithForm(petId: number, name?: string, status?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public updatePetWithForm(petId: number, name?: string, status?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public updatePetWithForm(petId: number, name?: string, status?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public updatePetWithForm(petId: number, name?: string, status?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { if (petId === null || petId === undefined) { throw new Error('Required parameter petId was null or undefined when calling updatePetWithForm.'); } + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (petstore_auth) required + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } // to determine the Content-Type header - let consumes: string[] = [ + const consumes: string[] = [ 'application/x-www-form-urlencoded' ]; - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - // authentication (petstore_auth) required - // oauth required - if (this.configuration.accessToken) - { - headers.set('Authorization', 'Bearer ' + this.configuration.accessToken); - } - - headers.set('Content-Type', 'application/x-www-form-urlencoded'); + const canConsumeForm = this.canConsumeForm(consumes); + let localVarFormParams: { append(param: string, value: any): any; }; + let localVarUseForm = false; + let localVarConvertFormParamsToString = false; + if (localVarUseForm) { + localVarFormParams = new FormData(); + } else { + localVarFormParams = new HttpParams({encoder: this.encoder}); + } if (name !== undefined) { - formParams.set('name', name); + localVarFormParams = localVarFormParams.append('name', name) as any || localVarFormParams; } if (status !== undefined) { - formParams.set('status', status); + localVarFormParams = localVarFormParams.append('status', status) as any || localVarFormParams; } - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Post, - headers: headers, - body: formParams.toString(), - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } } - return this.http.request(path, requestOptions); + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, + localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * 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 uploadFileWithHttpInfo(petId: number, additionalMetadata?: string, file?: any, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/pet/${petId}/uploadImage`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - let formParams = new URLSearchParams(); - - // verify required parameter 'petId' is not null or undefined + public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; + public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { if (petId === null || petId === undefined) { throw new Error('Required parameter petId was null or undefined when calling uploadFile.'); } + let localVarHeaders = this.defaultHeaders; + + let localVarCredential: string | undefined; + // authentication (petstore_auth) required + localVarCredential = this.configuration.lookupCredential('petstore_auth'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); + } + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } // to determine the Content-Type header - let consumes: string[] = [ + const consumes: string[] = [ 'multipart/form-data' ]; - // to determine the Accept header - let produces: string[] = [ - 'application/json' - ]; - - // authentication (petstore_auth) required - // oauth required - if (this.configuration.accessToken) - { - headers.set('Authorization', 'Bearer ' + this.configuration.accessToken); - } - - headers.set('Content-Type', 'application/x-www-form-urlencoded'); + const canConsumeForm = this.canConsumeForm(consumes); + let localVarFormParams: { append(param: string, value: any): any; }; + let localVarUseForm = false; + let localVarConvertFormParamsToString = 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 + localVarUseForm = canConsumeForm; + if (localVarUseForm) { + localVarFormParams = new FormData(); + } else { + localVarFormParams = new HttpParams({encoder: this.encoder}); + } if (additionalMetadata !== undefined) { - formParams.set('additionalMetadata', additionalMetadata); + localVarFormParams = localVarFormParams.append('additionalMetadata', additionalMetadata) as any || localVarFormParams; } if (file !== undefined) { - formParams.set('file', file); + localVarFormParams = localVarFormParams.append('file', file) as any || localVarFormParams; } - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Post, - headers: headers, - body: formParams.toString(), - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } } - return this.http.request(path, requestOptions); + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}/uploadImage`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, + localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/store.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/store.service.ts index edc5f2df5de..754df0c9625 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/store.service.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/store.service.ts @@ -1,313 +1,342 @@ /** - * Swagger Petstore - * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * 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. * - * OpenAPI spec version: 1.0.0 - * Contact: apiteam@swagger.io + * The version of the OpenAPI document: 1.0.0 + * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - -import { Inject, Injectable, Optional } from '@angular/core'; -import { Http, Headers, URLSearchParams } from '@angular/http'; -import { RequestMethod, RequestOptions, RequestOptionsArgs } from '@angular/http'; -import { Response, ResponseContentType } from '@angular/http'; - -import { Observable } from 'rxjs/Observable'; -import '../rxjs-operators'; - -import { Order } from '../model/order'; - -import { BASE_PATH } from '../variables'; -import { Configuration } from '../configuration'; - /* tslint:disable:no-unused-variable member-ordering */ +import { Inject, Injectable, Optional } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpParams, + HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + } from '@angular/common/http'; +import { CustomHttpParameterCodec } from '../encoder'; +import { Observable } from 'rxjs'; -@Injectable() +// @ts-ignore +import { Order } from '../model/order'; + +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + + + +@Injectable({ + providedIn: 'root' +}) export class StoreService { - protected basePath = 'http://petstore.swagger.io/v2'; - public defaultHeaders: Headers = new Headers(); - public configuration: Configuration = new Configuration(); - constructor(protected http: Http, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) { - if (basePath) { - this.basePath = basePath; - } + protected basePath = 'http://petstore.swagger.io/v2'; + public defaultHeaders = new HttpHeaders(); + public configuration = new Configuration(); + public encoder: HttpParameterCodec; + + constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { if (configuration) { this.configuration = configuration; - this.basePath = basePath || configuration.basePath || this.basePath; } - } - - /** - * - * Extends object by coping non-existing properties. - * @param objA object to be extended - * @param objB source object - */ - private extendObj(objA: T1, objB: T2) { - for(let key in objB){ - if(objB.hasOwnProperty(key)){ - objA[key] = objB[key]; + if (typeof this.configuration.basePath !== 'string') { + if (Array.isArray(basePath) && basePath.length > 0) { + basePath = basePath[0]; } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; } - return objA; + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + + + // @ts-ignore + private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { + if (typeof value === "object" && value instanceof Date === false) { + httpParams = this.addToHttpParamsRecursive(httpParams, value); + } else { + httpParams = this.addToHttpParamsRecursive(httpParams, value, key); + } + return httpParams; + } + + private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { + if (value == null) { + return httpParams; + } + + if (typeof value === "object") { + if (Array.isArray(value)) { + (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); + } else if (value instanceof Date) { + if (key != null) { + httpParams = httpParams.append(key, (value as Date).toISOString().substr(0, 10)); + } else { + throw Error("key may not be null if value is Date"); + } + } else { + Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( + httpParams, value[k], key != null ? `${key}.${k}` : k)); + } + } else if (key != null) { + httpParams = httpParams.append(key, value); + } else { + throw Error("key may not be null if value is not object or array"); + } + return httpParams; } /** * Delete purchase order by ID * For valid response try integer IDs with value < 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, extraHttpRequestParams?: any): Observable<{}> { - return this.deleteOrderWithHttpInfo(orderId, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Returns pet inventories by status - * Returns a map of status codes to quantities - */ - public getInventory(extraHttpRequestParams?: any): Observable<{ [key: string]: number; }> { - return this.getInventoryWithHttpInfo(extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Find purchase order by ID - * For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions - * @param orderId ID of pet that needs to be fetched - */ - public getOrderById(orderId: number, extraHttpRequestParams?: any): Observable { - return this.getOrderByIdWithHttpInfo(orderId, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Place an order for a pet - * - * @param body order placed for purchasing the pet - */ - public placeOrder(body: Order, extraHttpRequestParams?: any): Observable { - return this.placeOrderWithHttpInfo(body, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - - /** - * Delete purchase order by ID - * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors - * @param orderId ID of the order that needs to be deleted - */ - public deleteOrderWithHttpInfo(orderId: string, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/store/order/${orderId}`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'orderId' is not null or undefined + public deleteOrder(orderId: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public deleteOrder(orderId: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public deleteOrder(orderId: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public deleteOrder(orderId: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { if (orderId === null || orderId === undefined) { throw new Error('Required parameter orderId was null or undefined when calling deleteOrder.'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - - - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Delete, - headers: headers, - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - return this.http.request(path, requestOptions); + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * 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 getInventoryWithHttpInfo(extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/store/inventory`; + public getInventory(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<{ [key: string]: number; }>; + public getInventory(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public getInventory(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public getInventory(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 + let localVarHeaders = this.defaultHeaders; - - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/json' - ]; - + let localVarCredential: string | undefined; // authentication (api_key) required - if (this.configuration.apiKey) - { - headers.set('api_key', this.configuration.apiKey); - } - - - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Get, - headers: headers, - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + localVarCredential = this.configuration.lookupCredential('api_key'); + if (localVarCredential) { + localVarHeaders = localVarHeaders.set('api_key', localVarCredential); } - return this.http.request(path, requestOptions); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/store/inventory`; + return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * Find purchase order by ID * For valid response try integer IDs with value <= 5 or > 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 getOrderByIdWithHttpInfo(orderId: number, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/store/order/${orderId}`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'orderId' is not null or undefined + public getOrderById(orderId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; + public getOrderById(orderId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public getOrderById(orderId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public getOrderById(orderId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { if (orderId === null || orderId === undefined) { throw new Error('Required parameter orderId was null or undefined when calling getOrderById.'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - - - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Get, - headers: headers, - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - return this.http.request(path, requestOptions); + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * Place an order for a pet - * * @param body 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 placeOrderWithHttpInfo(body: Order, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/store/order`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'body' is not null or undefined + public placeOrder(body: Order, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; + public placeOrder(body: Order, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public placeOrder(body: Order, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public placeOrder(body: Order, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling placeOrder.'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - - - headers.set('Content-Type', 'application/json'); - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Post, - headers: headers, - body: body == null ? '' : JSON.stringify(body), // https://github.com/angular/angular/issues/10612 - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - return this.http.request(path, requestOptions); + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/store/order`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, + body, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/user.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/user.service.ts index 6c5eeee1b6b..83261777c31 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/user.service.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/user.service.ts @@ -1,522 +1,537 @@ /** - * Swagger Petstore - * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * 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. * - * OpenAPI spec version: 1.0.0 - * Contact: apiteam@swagger.io + * The version of the OpenAPI document: 1.0.0 + * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - -import { Inject, Injectable, Optional } from '@angular/core'; -import { Http, Headers, URLSearchParams } from '@angular/http'; -import { RequestMethod, RequestOptions, RequestOptionsArgs } from '@angular/http'; -import { Response, ResponseContentType } from '@angular/http'; - -import { Observable } from 'rxjs/Observable'; -import '../rxjs-operators'; - -import { User } from '../model/user'; - -import { BASE_PATH } from '../variables'; -import { Configuration } from '../configuration'; - /* tslint:disable:no-unused-variable member-ordering */ +import { Inject, Injectable, Optional } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpParams, + HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + } from '@angular/common/http'; +import { CustomHttpParameterCodec } from '../encoder'; +import { Observable } from 'rxjs'; -@Injectable() +// @ts-ignore +import { User } from '../model/user'; + +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + + + +@Injectable({ + providedIn: 'root' +}) export class UserService { - protected basePath = 'http://petstore.swagger.io/v2'; - public defaultHeaders: Headers = new Headers(); - public configuration: Configuration = new Configuration(); - constructor(protected http: Http, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) { - if (basePath) { - this.basePath = basePath; - } + protected basePath = 'http://petstore.swagger.io/v2'; + public defaultHeaders = new HttpHeaders(); + public configuration = new Configuration(); + public encoder: HttpParameterCodec; + + constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { if (configuration) { this.configuration = configuration; - this.basePath = basePath || configuration.basePath || this.basePath; } - } - - /** - * - * Extends object by coping non-existing properties. - * @param objA object to be extended - * @param objB source object - */ - private extendObj(objA: T1, objB: T2) { - for(let key in objB){ - if(objB.hasOwnProperty(key)){ - objA[key] = objB[key]; + if (typeof this.configuration.basePath !== 'string') { + if (Array.isArray(basePath) && basePath.length > 0) { + basePath = basePath[0]; } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; } - return objA; + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + + + // @ts-ignore + private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { + if (typeof value === "object" && value instanceof Date === false) { + httpParams = this.addToHttpParamsRecursive(httpParams, value); + } else { + httpParams = this.addToHttpParamsRecursive(httpParams, value, key); + } + return httpParams; + } + + private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { + if (value == null) { + return httpParams; + } + + if (typeof value === "object") { + if (Array.isArray(value)) { + (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); + } else if (value instanceof Date) { + if (key != null) { + httpParams = httpParams.append(key, (value as Date).toISOString().substr(0, 10)); + } else { + throw Error("key may not be null if value is Date"); + } + } else { + Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( + httpParams, value[k], key != null ? `${key}.${k}` : k)); + } + } else if (key != null) { + httpParams = httpParams.append(key, value); + } else { + throw Error("key may not be null if value is not object or array"); + } + return httpParams; } /** * Create user * This can only be done by the logged in user. * @param body 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(body: User, extraHttpRequestParams?: any): Observable<{}> { - return this.createUserWithHttpInfo(body, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Creates list of users with given input array - * - * @param body List of user object - */ - public createUsersWithArrayInput(body: Array, extraHttpRequestParams?: any): Observable<{}> { - return this.createUsersWithArrayInputWithHttpInfo(body, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Creates list of users with given input array - * - * @param body List of user object - */ - public createUsersWithListInput(body: Array, extraHttpRequestParams?: any): Observable<{}> { - return this.createUsersWithListInputWithHttpInfo(body, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Delete user - * This can only be done by the logged in user. - * @param username The name that needs to be deleted - */ - public deleteUser(username: string, extraHttpRequestParams?: any): Observable<{}> { - return this.deleteUserWithHttpInfo(username, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Get user by user name - * - * @param username The name that needs to be fetched. Use user1 for testing. - */ - public getUserByName(username: string, extraHttpRequestParams?: any): Observable { - return this.getUserByNameWithHttpInfo(username, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Logs user into the system - * - * @param username The user name for login - * @param password The password for login in clear text - */ - public loginUser(username: string, password: string, extraHttpRequestParams?: any): Observable { - return this.loginUserWithHttpInfo(username, password, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Logs out current logged in user session - * - */ - public logoutUser(extraHttpRequestParams?: any): Observable<{}> { - return this.logoutUserWithHttpInfo(extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - /** - * Updated user - * This can only be done by the logged in user. - * @param username name that need to be deleted - * @param body Updated user object - */ - public updateUser(username: string, body: User, extraHttpRequestParams?: any): Observable<{}> { - return this.updateUserWithHttpInfo(username, body, extraHttpRequestParams) - .map((response: Response) => { - if (response.status === 204) { - return undefined; - } else { - return response.json(); - } - }); - } - - - /** - * Create user - * This can only be done by the logged in user. - * @param body Created user object - */ - public createUserWithHttpInfo(body: User, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/user`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'body' is not null or undefined + public createUser(body: User, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public createUser(body: User, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public createUser(body: User, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public createUser(body: User, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling createUser.'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - - - headers.set('Content-Type', 'application/json'); - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Post, - headers: headers, - body: body == null ? '' : JSON.stringify(body), // https://github.com/angular/angular/issues/10612 - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - return this.http.request(path, requestOptions); + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, + body, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * Creates list of users with given input array - * * @param body 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 createUsersWithArrayInputWithHttpInfo(body: Array, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/user/createWithArray`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'body' is not null or undefined + public createUsersWithArrayInput(body: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public createUsersWithArrayInput(body: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public createUsersWithArrayInput(body: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public createUsersWithArrayInput(body: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling createUsersWithArrayInput.'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - - - headers.set('Content-Type', 'application/json'); - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Post, - headers: headers, - body: body == null ? '' : JSON.stringify(body), // https://github.com/angular/angular/issues/10612 - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - return this.http.request(path, requestOptions); + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/createWithArray`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, + body, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * Creates list of users with given input array - * * @param body 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 createUsersWithListInputWithHttpInfo(body: Array, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/user/createWithList`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'body' is not null or undefined + public createUsersWithListInput(body: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public createUsersWithListInput(body: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public createUsersWithListInput(body: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public createUsersWithListInput(body: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling createUsersWithListInput.'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - - - headers.set('Content-Type', 'application/json'); - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Post, - headers: headers, - body: body == null ? '' : JSON.stringify(body), // https://github.com/angular/angular/issues/10612 - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - return this.http.request(path, requestOptions); + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/createWithList`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, + body, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * 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 deleteUserWithHttpInfo(username: string, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/user/${username}`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'username' is not null or undefined + public deleteUser(username: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public deleteUser(username: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public deleteUser(username: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public deleteUser(username: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { if (username === null || username === undefined) { throw new Error('Required parameter username was null or undefined when calling deleteUser.'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - - - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Delete, - headers: headers, - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - return this.http.request(path, requestOptions); + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * 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 getUserByNameWithHttpInfo(username: string, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/user/${username}`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'username' is not null or undefined + public getUserByName(username: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; + public getUserByName(username: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public getUserByName(username: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public getUserByName(username: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { if (username === null || username === undefined) { throw new Error('Required parameter username was null or undefined when calling getUserByName.'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - - - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Get, - headers: headers, - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - return this.http.request(path, requestOptions); + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * 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 loginUserWithHttpInfo(username: string, password: string, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/user/login`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'username' is not null or undefined + public loginUser(username: string, password: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; + public loginUser(username: string, password: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public loginUser(username: string, password: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; + public loginUser(username: string, password: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { if (username === null || username === undefined) { throw new Error('Required parameter username was null or undefined when calling loginUser.'); } - // verify required parameter 'password' is not null or undefined if (password === null || password === undefined) { throw new Error('Required parameter password was null or undefined when calling loginUser.'); } - if (username !== undefined) { - queryParameters.set('username', username); + + let localVarQueryParameters = new HttpParams({encoder: this.encoder}); + if (username !== undefined && username !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + username, 'username'); } - if (password !== undefined) { - queryParameters.set('password', password); + if (password !== undefined && password !== null) { + localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, + password, 'password'); + } + + let localVarHeaders = this.defaultHeaders; + + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + 'application/xml', + 'application/json' + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); + } + + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); } - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - - - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Get, - headers: headers, - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } } - return this.http.request(path, requestOptions); + let localVarPath = `/user/login`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + params: localVarQueryParameters, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** * 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 logoutUserWithHttpInfo(extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/user/logout`; + public logoutUser(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public logoutUser(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public logoutUser(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public logoutUser(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 + let localVarHeaders = this.defaultHeaders; - - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - - - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Get, - headers: headers, - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - return this.http.request(path, requestOptions); + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/logout`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } /** @@ -524,50 +539,70 @@ export class UserService { * This can only be done by the logged in user. * @param username name that need to be deleted * @param body 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 updateUserWithHttpInfo(username: string, body: User, extraHttpRequestParams?: any): Observable { - const path = this.basePath + `/user/${username}`; - - let queryParameters = new URLSearchParams(); - let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845 - // verify required parameter 'username' is not null or undefined + public updateUser(username: string, body: User, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; + public updateUser(username: string, body: User, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public updateUser(username: string, body: User, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; + public updateUser(username: string, body: User, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { if (username === null || username === undefined) { throw new Error('Required parameter username was null or undefined when calling updateUser.'); } - // verify required parameter 'body' is not null or undefined if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling updateUser.'); } + let localVarHeaders = this.defaultHeaders; - // to determine the Content-Type header - let consumes: string[] = [ - ]; - - // to determine the Accept header - let produces: string[] = [ - 'application/xml', - 'application/json' - ]; - - - - headers.set('Content-Type', 'application/json'); - - - let requestOptions: RequestOptionsArgs = new RequestOptions({ - method: RequestMethod.Put, - headers: headers, - body: body == null ? '' : JSON.stringify(body), // https://github.com/angular/angular/issues/10612 - search: queryParameters - }); - - // https://github.com/swagger-api/swagger-codegen/issues/4037 - if (extraHttpRequestParams) { - requestOptions = this.extendObj(requestOptions, extraHttpRequestParams); + let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; + if (localVarHttpHeaderAcceptSelected === undefined) { + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); + } + if (localVarHttpHeaderAcceptSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - return this.http.request(path, requestOptions); + let localVarHttpContext: HttpContext | undefined = options && options.context; + if (localVarHttpContext === undefined) { + localVarHttpContext = new HttpContext(); + } + + + // to determine the Content-Type header + const consumes: string[] = [ + ]; + const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); + if (httpContentTypeSelected !== undefined) { + localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); + } + + let responseType_: 'text' | 'json' | 'blob' = 'json'; + if (localVarHttpHeaderAcceptSelected) { + if (localVarHttpHeaderAcceptSelected.startsWith('text')) { + responseType_ = 'text'; + } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { + responseType_ = 'json'; + } else { + responseType_ = 'blob'; + } + } + + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, + body, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); } } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/configuration.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/configuration.ts index ec087d2b0c8..5ea92c82cb6 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/configuration.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/configuration.ts @@ -1,24 +1,186 @@ +import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; + export interface ConfigurationParameters { - apiKey?: string; - username?: string; - password?: string; - accessToken?: string; - basePath?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ + encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; + /** + * The keys are the names in the securitySchemes section of the OpenAPI + * document. They should map to the value used for authentication + * minus any standard prefixes such as 'Basic' or 'Bearer'. + */ + credentials?: {[ key: string ]: string | (() => string | undefined)}; } export class Configuration { - apiKey: string; - username: string; - password: string; - accessToken: string; - basePath: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + /** + * @deprecated Since 5.0. Use credentials instead + */ + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ + encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; + /** + * The keys are the names in the securitySchemes section of the OpenAPI + * document. They should map to the value used for authentication + * minus any standard prefixes such as 'Basic' or 'Bearer'. + */ + credentials: {[ key: string ]: string | (() => string | undefined)}; + constructor(configurationParameters: 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; + this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } + if (configurationParameters.credentials) { + this.credentials = configurationParameters.credentials; + } + else { + this.credentials = {}; + } - constructor(configurationParameters: ConfigurationParameters = {}) { - this.apiKey = configurationParameters.apiKey; - this.username = configurationParameters.username; - this.password = configurationParameters.password; - this.accessToken = configurationParameters.accessToken; - this.basePath = configurationParameters.basePath; - } + // init default api_key credential + if (!this.credentials['api_key']) { + this.credentials['api_key'] = () => { + if (this.apiKeys === null || this.apiKeys === undefined) { + return undefined; + } else { + return this.apiKeys['api_key'] || this.apiKeys['api_key']; + } + }; + } + + // init default petstore_auth credential + if (!this.credentials['petstore_auth']) { + this.credentials['petstore_auth'] = () => { + return typeof this.accessToken === 'function' + ? this.accessToken() + : this.accessToken; + }; + } + } + + /** + * 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 undefined if no selection could be made. + */ + public selectHeaderContentType (contentTypes: string[]): string | undefined { + if (contentTypes.length === 0) { + return undefined; + } + + const type = contentTypes.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return contentTypes[0]; + } + return type; + } + + /** + * Select the correct accept content-type to use for a request. + * Uses {@link 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 undefined if no selection could be made. + */ + public selectHeaderAccept(accepts: string[]): string | undefined { + if (accepts.length === 0) { + return undefined; + } + + const type = accepts.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return accepts[0]; + } + return type; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } + + public lookupCredential(key: string): string | undefined { + const value = this.credentials[key]; + return typeof value === 'function' + ? value() + : value; + } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/encoder.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/encoder.ts new file mode 100644 index 00000000000..138c4d5cf2c --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/encoder.ts @@ -0,0 +1,20 @@ +import { HttpParameterCodec } from '@angular/common/http'; + +/** + * Custom HttpParameterCodec + * Workaround for https://github.com/angular/angular/issues/18261 + */ +export class CustomHttpParameterCodec implements HttpParameterCodec { + encodeKey(k: string): string { + return encodeURIComponent(k); + } + encodeValue(v: string): string { + return encodeURIComponent(v); + } + decodeKey(k: string): string { + return decodeURIComponent(k); + } + decodeValue(v: string): string { + return decodeURIComponent(v); + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/git_push.sh b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/git_push.sh index 484e8cc0033..67b52e22d7f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/git_push.sh +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/git_push.sh @@ -1,11 +1,17 @@ #!/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 swagger-petstore-perl "minor update" +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" git_user_id=$1 git_repo_id=$2 release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi if [ "$git_user_id" = "" ]; then git_user_id="" @@ -28,7 +34,7 @@ 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. +# Commits the tracked changes and prepares them to be pushed to a remote repository. git commit -m "$release_note" # Sets the new remote @@ -37,9 +43,9 @@ if [ "$git_remote" = "" ]; then # git remote not defined if [ "$GIT_TOKEN" = "" ]; then echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." - git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + 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}"@github.com/${git_user_id}/${git_repo_id}.git + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git fi fi @@ -47,6 +53,5 @@ fi git pull origin master # Pushes (Forces) the changes in the local repository up to the remote repository -echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" git push origin master 2>&1 | grep -v 'To https' - diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/index.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/index.ts index c312b70fa3e..104dd3d21e3 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/index.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/index.ts @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/apiResponse.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/apiResponse.ts index 8b880303aae..ca96abca935 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/apiResponse.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/apiResponse.ts @@ -1,34 +1,19 @@ /** - * Swagger Petstore - * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * 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. * - * OpenAPI spec version: 1.0.0 - * Contact: apiteam@swagger.io + * The version of the OpenAPI document: 1.0.0 + * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - -export interface ApiResponse { +export interface ApiResponse { code?: number; - type?: string; - message?: string; - } + diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/category.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/category.ts index 53f4c456135..4e435cae1db 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/category.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/category.ts @@ -1,32 +1,18 @@ /** - * Swagger Petstore - * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * 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. * - * OpenAPI spec version: 1.0.0 - * Contact: apiteam@swagger.io + * The version of the OpenAPI document: 1.0.0 + * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - -export interface Category { +export interface Category { id?: number; - name?: string; - } + diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/order.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/order.ts index 5086f6011cd..a730d4c1757 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/order.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/order.ts @@ -1,50 +1,34 @@ /** - * Swagger Petstore - * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * 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. * - * OpenAPI spec version: 1.0.0 - * Contact: apiteam@swagger.io + * The version of the OpenAPI document: 1.0.0 + * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - -export interface Order { +export interface Order { id?: number; - petId?: number; - quantity?: number; - - shipDate?: Date; - + shipDate?: string; /** * Order Status */ status?: Order.StatusEnum; - complete?: boolean; - } export namespace Order { - export enum StatusEnum { - Placed = 'placed', - Approved = 'approved', - Delivered = 'delivered' - } + export type StatusEnum = 'placed' | 'approved' | 'delivered'; + export const StatusEnum = { + Placed: 'placed' as StatusEnum, + Approved: 'approved' as StatusEnum, + Delivered: 'delivered' as StatusEnum + }; } + + diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/pet.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/pet.ts index f61abab4a2e..284185ddd1f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/pet.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/pet.ts @@ -1,52 +1,36 @@ /** - * Swagger Petstore - * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * 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. * - * OpenAPI spec version: 1.0.0 - * Contact: apiteam@swagger.io + * The version of the OpenAPI document: 1.0.0 + * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - import { Category } from './category'; import { Tag } from './tag'; -export interface Pet { +export interface Pet { id?: number; - category?: Category; - name: string; - photoUrls: Array; - tags?: Array; - /** * pet status in the store */ status?: Pet.StatusEnum; - } export namespace Pet { - export enum StatusEnum { - Available = 'available', - Pending = 'pending', - Sold = 'sold' - } + export type StatusEnum = 'available' | 'pending' | 'sold'; + export const StatusEnum = { + Available: 'available' as StatusEnum, + Pending: 'pending' as StatusEnum, + Sold: 'sold' as StatusEnum + }; } + + diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/tag.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/tag.ts index 7e59927e223..73dee10beb5 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/tag.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/tag.ts @@ -1,32 +1,18 @@ /** - * Swagger Petstore - * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * 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. * - * OpenAPI spec version: 1.0.0 - * Contact: apiteam@swagger.io + * The version of the OpenAPI document: 1.0.0 + * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - -export interface Tag { +export interface Tag { id?: number; - name?: string; - } + diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/user.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/user.ts index 71bfdedd404..b3c99357e79 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/user.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/user.ts @@ -1,47 +1,27 @@ /** - * Swagger Petstore - * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * 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. * - * OpenAPI spec version: 1.0.0 - * Contact: apiteam@swagger.io + * The version of the OpenAPI document: 1.0.0 + * * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech * Do not edit the class manually. - * - * 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. */ - -export interface User { +export interface User { id?: number; - username?: string; - firstName?: string; - lastName?: string; - email?: string; - password?: string; - phone?: string; - /** * User Status */ userStatus?: number; - } + diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/ng-package.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/ng-package.json new file mode 100644 index 00000000000..3b17900dc9c --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/ng-package.json @@ -0,0 +1,6 @@ +{ + "$schema": "./node_modules/ng-packagr/ng-package.schema.json", + "lib": { + "entryFile": "index.ts" + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/package.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/package.json index 720ddd966f6..685877325a2 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/package.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/package.json @@ -1,38 +1,34 @@ { "name": "petstore-integration-test", "version": "1.0.3", - "description": "swagger client for petstore-integration-test", - "author": "Swagger Codegen Contributors", + "description": "OpenAPI client for petstore-integration-test", + "author": "OpenAPI-Generator Contributors", + "repository": { + "type": "git", + "url": "https:////.git" + }, "keywords": [ - "swagger-client" + "openapi-client", + "openapi-generator" ], - "license": "Apache-2.0", - "main": "dist/index.js", - "typings": "dist/index.d.ts", + "license": "Unlicense", "scripts": { - "build": "typings install && tsc --outDir dist/" + "build": "ng-packagr -p ng-package.json" }, "peerDependencies": { - "@angular/core": "^2.0.0", - "@angular/http": "^2.0.0", - "@angular/common": "^2.0.0", - "@angular/compiler": "^2.0.0", - "core-js": "^2.4.0", - "reflect-metadata": "^0.1.3", - "rxjs": "5.0.0-beta.12", - "zone.js": "^0.6.17" + "@angular/core": "^14.0.5", + "rxjs": "^7.5.5" }, "devDependencies": { - "@angular/core": "^2.0.0", - "@angular/http": "^2.0.0", - "@angular/common": "^2.0.0", - "@angular/compiler": "^2.0.0", - "@angular/platform-browser": "^2.0.0", - "core-js": "^2.4.0", + "@angular/common": "^14.0.5", + "@angular/compiler": "^14.0.5", + "@angular/compiler-cli": "^14.0.5", + "@angular/core": "^14.0.5", + "@angular/platform-browser": "^14.0.5", + "ng-packagr": "^14.0.2", "reflect-metadata": "^0.1.3", - "rxjs": "5.0.0-beta.12", - "zone.js": "^0.6.17", - "typescript": "^4.0", - "typings": "^1.3.2" - } -} + "rxjs": "^7.5.5", + "tsickle": "^0.46.3", + "typescript": ">=4.6.0 <=4.8.0", + "zone.js": "^0.11.5" + }} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/param.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/rxjs-operators.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/rxjs-operators.ts deleted file mode 100644 index 5659cd0694f..00000000000 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/rxjs-operators.ts +++ /dev/null @@ -1,11 +0,0 @@ -// RxJS imports according to https://angular.io/docs/ts/latest/guide/server-communication.html#!#rxjs - -// See node_module/rxjs/Rxjs.js -// Import just the rxjs statics and operators we need for THIS app. - -// Statics -import 'rxjs/add/observable/throw'; - -// Operators -import 'rxjs/add/operator/catch'; -import 'rxjs/add/operator/map'; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/tsconfig.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/tsconfig.json index e1f949692b6..c01ebe255d4 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/tsconfig.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/tsconfig.json @@ -1,28 +1,28 @@ { - "compilerOptions": { - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "noImplicitAny": false, - "suppressImplicitAnyIndexErrors": true, - "target": "es5", - "module": "commonjs", - "moduleResolution": "node", - "removeComments": true, - "sourceMap": true, - "outDir": "./lib", - "noLib": false, - "declaration": true - }, - "exclude": [ - "node_modules", - "typings/main.d.ts", - "typings/main", - "lib", - "dist" - ], - "filesGlob": [ - "./model/*.ts", - "./api/*.ts", - "typings/browser.d.ts" - ] + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "noImplicitAny": false, + "suppressImplicitAnyIndexErrors": true, + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "removeComments": true, + "sourceMap": true, + "outDir": "./dist", + "noLib": false, + "declaration": true, + "lib": [ "es6", "dom" ], + "typeRoots": [ + "node_modules/@types" + ] + }, + "exclude": [ + "node_modules", + "dist" + ], + "filesGlob": [ + "./model/*.ts", + "./api/*.ts" + ] } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/typings.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/typings.json deleted file mode 100644 index 507c40e5cbe..00000000000 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/typings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "globalDependencies": { - "core-js": "registry:dt/core-js#0.0.0+20160725163759" - } -} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/variables.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/variables.ts index 27b987e9b23..6fe58549f39 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/variables.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/variables.ts @@ -1,3 +1,9 @@ -import { OpaqueToken } from '@angular/core'; +import { InjectionToken } from '@angular/core'; -export const BASE_PATH = new OpaqueToken('basePath'); \ No newline at end of file +export const BASE_PATH = new InjectionToken('basePath'); +export const COLLECTION_FORMATS = { + 'csv': ',', + 'tsv': ' ', + 'ssv': ' ', + 'pipes': '|' +} diff --git a/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/.openapi-generator/FILES b/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/.openapi-generator/FILES index e646d434eee..6cf24d465b2 100644 --- a/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/.openapi-generator/FILES +++ b/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/.openapi-generator/FILES @@ -11,4 +11,5 @@ model/apple.ts model/fruit.ts model/grape.ts model/models.ts +param.ts variables.ts diff --git a/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/README.md b/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/README.md index f2e5a1c1ee2..de16f95a8bd 100644 --- a/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/README.md +++ b/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/README.md @@ -201,3 +201,26 @@ import { environment } from '../environments/environment'; }) export class AppModule { } ``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/api/default.service.ts b/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/api/default.service.ts index 2e1dc9e1677..df2c94ed3e8 100644 --- a/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/api/default.service.ts +++ b/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/api/default.service.ts @@ -131,7 +131,8 @@ export class DefaultService { } } - return this.httpClient.get(`${this.configuration.basePath}/`, + let localVarPath = `/`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -192,7 +193,8 @@ export class DefaultService { } } - return this.httpClient.put(`${this.configuration.basePath}/`, + let localVarPath = `/`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/configuration.ts b/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/configuration.ts index 4ca3546927f..d38a4c153f2 100644 --- a/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/configuration.ts +++ b/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/configuration.ts @@ -1,4 +1,5 @@ import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; export interface ConfigurationParameters { /** @@ -13,7 +14,18 @@ export interface ConfigurationParameters { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -35,7 +47,18 @@ export class Configuration { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -51,6 +74,12 @@ export class Configuration { this.basePath = configurationParameters.basePath; this.withCredentials = configurationParameters.withCredentials; this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } if (configurationParameters.credentials) { this.credentials = configurationParameters.credentials; } @@ -118,4 +147,20 @@ export class Configuration { ? value() : value; } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/index.ts b/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/index.ts index c312b70fa3e..104dd3d21e3 100644 --- a/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/index.ts +++ b/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/index.ts @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/param.ts b/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/samples/client/petstore/typescript-angular-v12-oneOf/builds/default/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/.openapi-generator/FILES b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/.openapi-generator/FILES index 7f8ebffb302..6e213a61aa6 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/.openapi-generator/FILES +++ b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/.openapi-generator/FILES @@ -16,4 +16,5 @@ model/order.ts model/pet.ts model/tag.ts model/user.ts +param.ts variables.ts diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/README.md b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/README.md index f2e5a1c1ee2..de16f95a8bd 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/README.md +++ b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/README.md @@ -201,3 +201,26 @@ import { environment } from '../environments/environment'; }) export class AppModule { } ``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/api/pet.service.ts b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/api/pet.service.ts index 8bfd88831c1..f3638c7b80e 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/api/pet.service.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/api/pet.service.ts @@ -167,7 +167,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -235,7 +236,8 @@ export class PetService { } } - return this.httpClient.delete(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -307,7 +309,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByStatus`, + let localVarPath = `/pet/findByStatus`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -381,7 +384,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByTags`, + let localVarPath = `/pet/findByTags`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -448,7 +452,8 @@ export class PetService { } } - return this.httpClient.get(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -521,7 +526,8 @@ export class PetService { } } - return this.httpClient.put(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -609,7 +615,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, @@ -701,7 +708,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}/uploadImage`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}/uploadImage`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/api/store.service.ts b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/api/store.service.ts index 540439245e6..e74edb114d9 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/api/store.service.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/api/store.service.ts @@ -136,7 +136,8 @@ export class StoreService { } } - return this.httpClient.delete(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -197,7 +198,8 @@ export class StoreService { } } - return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}/store/inventory`, + let localVarPath = `/store/inventory`; + return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -256,7 +258,8 @@ export class StoreService { } } - return this.httpClient.get(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -322,7 +325,8 @@ export class StoreService { } } - return this.httpClient.post(`${this.configuration.basePath}/store/order`, + let localVarPath = `/store/order`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/api/user.service.ts b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/api/user.service.ts index a248e37947e..f45439fe6fd 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/api/user.service.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/api/user.service.ts @@ -144,7 +144,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user`, + let localVarPath = `/user`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -209,7 +210,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithArray`, + let localVarPath = `/user/createWithArray`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -274,7 +276,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithList`, + let localVarPath = `/user/createWithList`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -332,7 +335,8 @@ export class UserService { } } - return this.httpClient.delete(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -390,7 +394,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -462,7 +467,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/login`, + let localVarPath = `/user/login`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -515,7 +521,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/logout`, + let localVarPath = `/user/logout`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -584,7 +591,8 @@ export class UserService { } } - return this.httpClient.put(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/configuration.ts b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/configuration.ts index 6fc0f80d973..5ea92c82cb6 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/configuration.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/configuration.ts @@ -1,4 +1,5 @@ import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; export interface ConfigurationParameters { /** @@ -13,7 +14,18 @@ export interface ConfigurationParameters { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -35,7 +47,18 @@ export class Configuration { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -51,6 +74,12 @@ export class Configuration { this.basePath = configurationParameters.basePath; this.withCredentials = configurationParameters.withCredentials; this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } if (configurationParameters.credentials) { this.credentials = configurationParameters.credentials; } @@ -138,4 +167,20 @@ export class Configuration { ? value() : value; } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/index.ts b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/index.ts index c312b70fa3e..104dd3d21e3 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/index.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/index.ts @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/param.ts b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/.openapi-generator/FILES b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/.openapi-generator/FILES index 7f8ebffb302..6e213a61aa6 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/.openapi-generator/FILES +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/.openapi-generator/FILES @@ -16,4 +16,5 @@ model/order.ts model/pet.ts model/tag.ts model/user.ts +param.ts variables.ts diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/README.md b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/README.md index f2e5a1c1ee2..de16f95a8bd 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/README.md +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/README.md @@ -201,3 +201,26 @@ import { environment } from '../environments/environment'; }) export class AppModule { } ``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/api/pet.service.ts b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/api/pet.service.ts index 337ff4debde..7c16b4bd412 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/api/pet.service.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/api/pet.service.ts @@ -167,7 +167,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -235,7 +236,8 @@ export class PetService { } } - return this.httpClient.delete(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -307,7 +309,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByStatus`, + let localVarPath = `/pet/findByStatus`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -381,7 +384,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByTags`, + let localVarPath = `/pet/findByTags`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -448,7 +452,8 @@ export class PetService { } } - return this.httpClient.get(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -521,7 +526,8 @@ export class PetService { } } - return this.httpClient.put(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -609,7 +615,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, @@ -701,7 +708,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}/uploadImage`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}/uploadImage`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/api/store.service.ts b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/api/store.service.ts index 5b573afc3ad..754df0c9625 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/api/store.service.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/api/store.service.ts @@ -136,7 +136,8 @@ export class StoreService { } } - return this.httpClient.delete(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -197,7 +198,8 @@ export class StoreService { } } - return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}/store/inventory`, + let localVarPath = `/store/inventory`; + return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -256,7 +258,8 @@ export class StoreService { } } - return this.httpClient.get(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -322,7 +325,8 @@ export class StoreService { } } - return this.httpClient.post(`${this.configuration.basePath}/store/order`, + let localVarPath = `/store/order`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/api/user.service.ts b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/api/user.service.ts index d2a215c6d93..26e8ad6f58c 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/api/user.service.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/api/user.service.ts @@ -144,7 +144,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user`, + let localVarPath = `/user`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -209,7 +210,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithArray`, + let localVarPath = `/user/createWithArray`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -274,7 +276,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithList`, + let localVarPath = `/user/createWithList`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -332,7 +335,8 @@ export class UserService { } } - return this.httpClient.delete(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -390,7 +394,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -462,7 +467,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/login`, + let localVarPath = `/user/login`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -515,7 +521,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/logout`, + let localVarPath = `/user/logout`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -584,7 +591,8 @@ export class UserService { } } - return this.httpClient.put(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/configuration.ts b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/configuration.ts index 6fc0f80d973..5ea92c82cb6 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/configuration.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/configuration.ts @@ -1,4 +1,5 @@ import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; export interface ConfigurationParameters { /** @@ -13,7 +14,18 @@ export interface ConfigurationParameters { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -35,7 +47,18 @@ export class Configuration { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -51,6 +74,12 @@ export class Configuration { this.basePath = configurationParameters.basePath; this.withCredentials = configurationParameters.withCredentials; this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } if (configurationParameters.credentials) { this.credentials = configurationParameters.credentials; } @@ -138,4 +167,20 @@ export class Configuration { ? value() : value; } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/index.ts b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/index.ts index c312b70fa3e..104dd3d21e3 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/index.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/index.ts @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/param.ts b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/default/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/.openapi-generator/FILES b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/.openapi-generator/FILES index 5db7bd76369..572424259e5 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/.openapi-generator/FILES +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/.openapi-generator/FILES @@ -18,5 +18,6 @@ model/tag.ts model/user.ts ng-package.json package.json +param.ts tsconfig.json variables.ts diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/README.md b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/README.md index 000c51d694b..4cd59003db3 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/README.md +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/README.md @@ -201,3 +201,26 @@ import { environment } from '../environments/environment'; }) export class AppModule { } ``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/api/pet.service.ts b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/api/pet.service.ts index 337ff4debde..7c16b4bd412 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/api/pet.service.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/api/pet.service.ts @@ -167,7 +167,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -235,7 +236,8 @@ export class PetService { } } - return this.httpClient.delete(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -307,7 +309,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByStatus`, + let localVarPath = `/pet/findByStatus`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -381,7 +384,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByTags`, + let localVarPath = `/pet/findByTags`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -448,7 +452,8 @@ export class PetService { } } - return this.httpClient.get(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -521,7 +526,8 @@ export class PetService { } } - return this.httpClient.put(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -609,7 +615,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, @@ -701,7 +708,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}/uploadImage`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}/uploadImage`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/api/store.service.ts b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/api/store.service.ts index 5b573afc3ad..754df0c9625 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/api/store.service.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/api/store.service.ts @@ -136,7 +136,8 @@ export class StoreService { } } - return this.httpClient.delete(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -197,7 +198,8 @@ export class StoreService { } } - return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}/store/inventory`, + let localVarPath = `/store/inventory`; + return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -256,7 +258,8 @@ export class StoreService { } } - return this.httpClient.get(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -322,7 +325,8 @@ export class StoreService { } } - return this.httpClient.post(`${this.configuration.basePath}/store/order`, + let localVarPath = `/store/order`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/api/user.service.ts b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/api/user.service.ts index d2a215c6d93..26e8ad6f58c 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/api/user.service.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/api/user.service.ts @@ -144,7 +144,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user`, + let localVarPath = `/user`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -209,7 +210,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithArray`, + let localVarPath = `/user/createWithArray`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -274,7 +276,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithList`, + let localVarPath = `/user/createWithList`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -332,7 +335,8 @@ export class UserService { } } - return this.httpClient.delete(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -390,7 +394,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -462,7 +467,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/login`, + let localVarPath = `/user/login`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -515,7 +521,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/logout`, + let localVarPath = `/user/logout`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -584,7 +591,8 @@ export class UserService { } } - return this.httpClient.put(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/configuration.ts b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/configuration.ts index 6fc0f80d973..5ea92c82cb6 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/configuration.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/configuration.ts @@ -1,4 +1,5 @@ import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; export interface ConfigurationParameters { /** @@ -13,7 +14,18 @@ export interface ConfigurationParameters { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -35,7 +47,18 @@ export class Configuration { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -51,6 +74,12 @@ export class Configuration { this.basePath = configurationParameters.basePath; this.withCredentials = configurationParameters.withCredentials; this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } if (configurationParameters.credentials) { this.credentials = configurationParameters.credentials; } @@ -138,4 +167,20 @@ export class Configuration { ? value() : value; } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/index.ts b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/index.ts index c312b70fa3e..104dd3d21e3 100644 --- a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/index.ts +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/index.ts @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/param.ts b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/samples/client/petstore/typescript-angular-v12-provided-in-root/builds/with-npm/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/.openapi-generator/FILES b/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/.openapi-generator/FILES index e646d434eee..6cf24d465b2 100644 --- a/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/.openapi-generator/FILES +++ b/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/.openapi-generator/FILES @@ -11,4 +11,5 @@ model/apple.ts model/fruit.ts model/grape.ts model/models.ts +param.ts variables.ts diff --git a/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/README.md b/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/README.md index f2e5a1c1ee2..de16f95a8bd 100644 --- a/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/README.md +++ b/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/README.md @@ -201,3 +201,26 @@ import { environment } from '../environments/environment'; }) export class AppModule { } ``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/api/default.service.ts b/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/api/default.service.ts index 2e1dc9e1677..df2c94ed3e8 100644 --- a/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/api/default.service.ts +++ b/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/api/default.service.ts @@ -131,7 +131,8 @@ export class DefaultService { } } - return this.httpClient.get(`${this.configuration.basePath}/`, + let localVarPath = `/`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -192,7 +193,8 @@ export class DefaultService { } } - return this.httpClient.put(`${this.configuration.basePath}/`, + let localVarPath = `/`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/configuration.ts b/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/configuration.ts index 4ca3546927f..d38a4c153f2 100644 --- a/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/configuration.ts +++ b/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/configuration.ts @@ -1,4 +1,5 @@ import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; export interface ConfigurationParameters { /** @@ -13,7 +14,18 @@ export interface ConfigurationParameters { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -35,7 +47,18 @@ export class Configuration { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -51,6 +74,12 @@ export class Configuration { this.basePath = configurationParameters.basePath; this.withCredentials = configurationParameters.withCredentials; this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } if (configurationParameters.credentials) { this.credentials = configurationParameters.credentials; } @@ -118,4 +147,20 @@ export class Configuration { ? value() : value; } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/index.ts b/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/index.ts index c312b70fa3e..104dd3d21e3 100644 --- a/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/index.ts +++ b/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/index.ts @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/param.ts b/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/samples/client/petstore/typescript-angular-v13-oneOf/builds/default/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/.openapi-generator/FILES b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/.openapi-generator/FILES index 7f8ebffb302..6e213a61aa6 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/.openapi-generator/FILES +++ b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/.openapi-generator/FILES @@ -16,4 +16,5 @@ model/order.ts model/pet.ts model/tag.ts model/user.ts +param.ts variables.ts diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/README.md b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/README.md index f2e5a1c1ee2..de16f95a8bd 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/README.md +++ b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/README.md @@ -201,3 +201,26 @@ import { environment } from '../environments/environment'; }) export class AppModule { } ``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/api/pet.service.ts b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/api/pet.service.ts index 8bfd88831c1..f3638c7b80e 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/api/pet.service.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/api/pet.service.ts @@ -167,7 +167,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -235,7 +236,8 @@ export class PetService { } } - return this.httpClient.delete(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -307,7 +309,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByStatus`, + let localVarPath = `/pet/findByStatus`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -381,7 +384,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByTags`, + let localVarPath = `/pet/findByTags`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -448,7 +452,8 @@ export class PetService { } } - return this.httpClient.get(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -521,7 +526,8 @@ export class PetService { } } - return this.httpClient.put(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -609,7 +615,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, @@ -701,7 +708,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}/uploadImage`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}/uploadImage`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/api/store.service.ts b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/api/store.service.ts index 540439245e6..e74edb114d9 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/api/store.service.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/api/store.service.ts @@ -136,7 +136,8 @@ export class StoreService { } } - return this.httpClient.delete(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -197,7 +198,8 @@ export class StoreService { } } - return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}/store/inventory`, + let localVarPath = `/store/inventory`; + return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -256,7 +258,8 @@ export class StoreService { } } - return this.httpClient.get(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -322,7 +325,8 @@ export class StoreService { } } - return this.httpClient.post(`${this.configuration.basePath}/store/order`, + let localVarPath = `/store/order`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/api/user.service.ts b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/api/user.service.ts index a248e37947e..f45439fe6fd 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/api/user.service.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/api/user.service.ts @@ -144,7 +144,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user`, + let localVarPath = `/user`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -209,7 +210,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithArray`, + let localVarPath = `/user/createWithArray`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -274,7 +276,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithList`, + let localVarPath = `/user/createWithList`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, @@ -332,7 +335,8 @@ export class UserService { } } - return this.httpClient.delete(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -390,7 +394,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -462,7 +467,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/login`, + let localVarPath = `/user/login`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -515,7 +521,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/logout`, + let localVarPath = `/user/logout`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -584,7 +591,8 @@ export class UserService { } } - return this.httpClient.put(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, body, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/configuration.ts b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/configuration.ts index 6fc0f80d973..5ea92c82cb6 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/configuration.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/configuration.ts @@ -1,4 +1,5 @@ import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; export interface ConfigurationParameters { /** @@ -13,7 +14,18 @@ export interface ConfigurationParameters { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -35,7 +47,18 @@ export class Configuration { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -51,6 +74,12 @@ export class Configuration { this.basePath = configurationParameters.basePath; this.withCredentials = configurationParameters.withCredentials; this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } if (configurationParameters.credentials) { this.credentials = configurationParameters.credentials; } @@ -138,4 +167,20 @@ export class Configuration { ? value() : value; } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/index.ts b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/index.ts index c312b70fa3e..104dd3d21e3 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/index.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/index.ts @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/param.ts b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/.openapi-generator/FILES b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/.openapi-generator/FILES index 7f8ebffb302..6e213a61aa6 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/.openapi-generator/FILES +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/.openapi-generator/FILES @@ -16,4 +16,5 @@ model/order.ts model/pet.ts model/tag.ts model/user.ts +param.ts variables.ts diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/README.md b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/README.md index f2e5a1c1ee2..de16f95a8bd 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/README.md +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/README.md @@ -201,3 +201,26 @@ import { environment } from '../environments/environment'; }) export class AppModule { } ``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/api/pet.service.ts b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/api/pet.service.ts index 6470114e4b6..04c3f1befbe 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/api/pet.service.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/api/pet.service.ts @@ -170,7 +170,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, pet, { context: localVarHttpContext, @@ -239,7 +240,8 @@ export class PetService { } } - return this.httpClient.delete(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -311,7 +313,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByStatus`, + let localVarPath = `/pet/findByStatus`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -385,7 +388,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByTags`, + let localVarPath = `/pet/findByTags`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -452,7 +456,8 @@ export class PetService { } } - return this.httpClient.get(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -528,7 +533,8 @@ export class PetService { } } - return this.httpClient.put(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, pet, { context: localVarHttpContext, @@ -617,7 +623,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, @@ -710,7 +717,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}/uploadImage`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}/uploadImage`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/api/store.service.ts b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/api/store.service.ts index b7825ee1f35..246a1826607 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/api/store.service.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/api/store.service.ts @@ -136,7 +136,8 @@ export class StoreService { } } - return this.httpClient.delete(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -197,7 +198,8 @@ export class StoreService { } } - return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}/store/inventory`, + let localVarPath = `/store/inventory`; + return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -256,7 +258,8 @@ export class StoreService { } } - return this.httpClient.get(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -324,7 +327,8 @@ export class StoreService { } } - return this.httpClient.post(`${this.configuration.basePath}/store/order`, + let localVarPath = `/store/order`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, order, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/api/user.service.ts b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/api/user.service.ts index 1ab01f930fa..b92dabef133 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/api/user.service.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/api/user.service.ts @@ -152,7 +152,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user`, + let localVarPath = `/user`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, user, { context: localVarHttpContext, @@ -226,7 +227,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithArray`, + let localVarPath = `/user/createWithArray`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, user, { context: localVarHttpContext, @@ -300,7 +302,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithList`, + let localVarPath = `/user/createWithList`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, user, { context: localVarHttpContext, @@ -365,7 +368,8 @@ export class UserService { } } - return this.httpClient.delete(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -424,7 +428,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -497,7 +502,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/login`, + let localVarPath = `/user/login`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -558,7 +564,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/logout`, + let localVarPath = `/user/logout`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -635,7 +642,8 @@ export class UserService { } } - return this.httpClient.put(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, user, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/configuration.ts b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/configuration.ts index 6fc0f80d973..5ea92c82cb6 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/configuration.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/configuration.ts @@ -1,4 +1,5 @@ import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; export interface ConfigurationParameters { /** @@ -13,7 +14,18 @@ export interface ConfigurationParameters { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -35,7 +47,18 @@ export class Configuration { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -51,6 +74,12 @@ export class Configuration { this.basePath = configurationParameters.basePath; this.withCredentials = configurationParameters.withCredentials; this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } if (configurationParameters.credentials) { this.credentials = configurationParameters.credentials; } @@ -138,4 +167,20 @@ export class Configuration { ? value() : value; } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/index.ts b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/index.ts index c312b70fa3e..104dd3d21e3 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/index.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/index.ts @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/param.ts b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/.openapi-generator/FILES b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/.openapi-generator/FILES index 5db7bd76369..572424259e5 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/.openapi-generator/FILES +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/.openapi-generator/FILES @@ -18,5 +18,6 @@ model/tag.ts model/user.ts ng-package.json package.json +param.ts tsconfig.json variables.ts diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/README.md b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/README.md index 000c51d694b..4cd59003db3 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/README.md +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/README.md @@ -201,3 +201,26 @@ import { environment } from '../environments/environment'; }) export class AppModule { } ``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/api/pet.service.ts b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/api/pet.service.ts index 6470114e4b6..04c3f1befbe 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/api/pet.service.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/api/pet.service.ts @@ -170,7 +170,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, pet, { context: localVarHttpContext, @@ -239,7 +240,8 @@ export class PetService { } } - return this.httpClient.delete(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -311,7 +313,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByStatus`, + let localVarPath = `/pet/findByStatus`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -385,7 +388,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByTags`, + let localVarPath = `/pet/findByTags`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -452,7 +456,8 @@ export class PetService { } } - return this.httpClient.get(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -528,7 +533,8 @@ export class PetService { } } - return this.httpClient.put(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, pet, { context: localVarHttpContext, @@ -617,7 +623,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, @@ -710,7 +717,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}/uploadImage`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}/uploadImage`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/api/store.service.ts b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/api/store.service.ts index b7825ee1f35..246a1826607 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/api/store.service.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/api/store.service.ts @@ -136,7 +136,8 @@ export class StoreService { } } - return this.httpClient.delete(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -197,7 +198,8 @@ export class StoreService { } } - return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}/store/inventory`, + let localVarPath = `/store/inventory`; + return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -256,7 +258,8 @@ export class StoreService { } } - return this.httpClient.get(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -324,7 +327,8 @@ export class StoreService { } } - return this.httpClient.post(`${this.configuration.basePath}/store/order`, + let localVarPath = `/store/order`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, order, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/api/user.service.ts b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/api/user.service.ts index 1ab01f930fa..b92dabef133 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/api/user.service.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/api/user.service.ts @@ -152,7 +152,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user`, + let localVarPath = `/user`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, user, { context: localVarHttpContext, @@ -226,7 +227,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithArray`, + let localVarPath = `/user/createWithArray`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, user, { context: localVarHttpContext, @@ -300,7 +302,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithList`, + let localVarPath = `/user/createWithList`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, user, { context: localVarHttpContext, @@ -365,7 +368,8 @@ export class UserService { } } - return this.httpClient.delete(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -424,7 +428,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -497,7 +502,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/login`, + let localVarPath = `/user/login`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -558,7 +564,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/logout`, + let localVarPath = `/user/logout`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -635,7 +642,8 @@ export class UserService { } } - return this.httpClient.put(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, user, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/configuration.ts b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/configuration.ts index 6fc0f80d973..5ea92c82cb6 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/configuration.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/configuration.ts @@ -1,4 +1,5 @@ import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; export interface ConfigurationParameters { /** @@ -13,7 +14,18 @@ export interface ConfigurationParameters { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -35,7 +47,18 @@ export class Configuration { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -51,6 +74,12 @@ export class Configuration { this.basePath = configurationParameters.basePath; this.withCredentials = configurationParameters.withCredentials; this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } if (configurationParameters.credentials) { this.credentials = configurationParameters.credentials; } @@ -138,4 +167,20 @@ export class Configuration { ? value() : value; } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/index.ts b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/index.ts index c312b70fa3e..104dd3d21e3 100644 --- a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/index.ts +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/index.ts @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/param.ts b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +} diff --git a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/.openapi-generator/FILES b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/.openapi-generator/FILES index 7f8ebffb302..6e213a61aa6 100644 --- a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/.openapi-generator/FILES +++ b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/.openapi-generator/FILES @@ -16,4 +16,5 @@ model/order.ts model/pet.ts model/tag.ts model/user.ts +param.ts variables.ts diff --git a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/README.md b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/README.md index f2e5a1c1ee2..de16f95a8bd 100644 --- a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/README.md +++ b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/README.md @@ -201,3 +201,26 @@ import { environment } from '../environments/environment'; }) export class AppModule { } ``` + +### Customizing path parameter encoding + +Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple' +and Dates for format 'date-time' are encoded correctly. + +Other styles (e.g. "matrix") are not that easy to encode +and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]). + +To implement your own parameter encoding (or call another library), +pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object +(see [General Usage](#general-usage) above). + +Example value for use in your Configuration-Provider: +```typescript +new Configuration({ + encodeParam: (param: Param) => myFancyParamEncoder(param), +}) +``` + +[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations +[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values +[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander diff --git a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/api/pet.service.ts b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/api/pet.service.ts index 6470114e4b6..04c3f1befbe 100644 --- a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/api/pet.service.ts +++ b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/api/pet.service.ts @@ -170,7 +170,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, pet, { context: localVarHttpContext, @@ -239,7 +240,8 @@ export class PetService { } } - return this.httpClient.delete(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -311,7 +313,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByStatus`, + let localVarPath = `/pet/findByStatus`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -385,7 +388,8 @@ export class PetService { } } - return this.httpClient.get>(`${this.configuration.basePath}/pet/findByTags`, + let localVarPath = `/pet/findByTags`; + return this.httpClient.get>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -452,7 +456,8 @@ export class PetService { } } - return this.httpClient.get(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -528,7 +533,8 @@ export class PetService { } } - return this.httpClient.put(`${this.configuration.basePath}/pet`, + let localVarPath = `/pet`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, pet, { context: localVarHttpContext, @@ -617,7 +623,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, @@ -710,7 +717,8 @@ export class PetService { } } - return this.httpClient.post(`${this.configuration.basePath}/pet/${encodeURIComponent(String(petId))}/uploadImage`, + let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}/uploadImage`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/api/store.service.ts b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/api/store.service.ts index b7825ee1f35..246a1826607 100644 --- a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/api/store.service.ts +++ b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/api/store.service.ts @@ -136,7 +136,8 @@ export class StoreService { } } - return this.httpClient.delete(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -197,7 +198,8 @@ export class StoreService { } } - return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}/store/inventory`, + let localVarPath = `/store/inventory`; + return this.httpClient.get<{ [key: string]: number; }>(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -256,7 +258,8 @@ export class StoreService { } } - return this.httpClient.get(`${this.configuration.basePath}/store/order/${encodeURIComponent(String(orderId))}`, + let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -324,7 +327,8 @@ export class StoreService { } } - return this.httpClient.post(`${this.configuration.basePath}/store/order`, + let localVarPath = `/store/order`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, order, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/api/user.service.ts b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/api/user.service.ts index 1ab01f930fa..b92dabef133 100644 --- a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/api/user.service.ts +++ b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/api/user.service.ts @@ -152,7 +152,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user`, + let localVarPath = `/user`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, user, { context: localVarHttpContext, @@ -226,7 +227,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithArray`, + let localVarPath = `/user/createWithArray`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, user, { context: localVarHttpContext, @@ -300,7 +302,8 @@ export class UserService { } } - return this.httpClient.post(`${this.configuration.basePath}/user/createWithList`, + let localVarPath = `/user/createWithList`; + return this.httpClient.post(`${this.configuration.basePath}${localVarPath}`, user, { context: localVarHttpContext, @@ -365,7 +368,8 @@ export class UserService { } } - return this.httpClient.delete(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.delete(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -424,7 +428,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -497,7 +502,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/login`, + let localVarPath = `/user/login`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, params: localVarQueryParameters, @@ -558,7 +564,8 @@ export class UserService { } } - return this.httpClient.get(`${this.configuration.basePath}/user/logout`, + let localVarPath = `/user/logout`; + return this.httpClient.get(`${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, @@ -635,7 +642,8 @@ export class UserService { } } - return this.httpClient.put(`${this.configuration.basePath}/user/${encodeURIComponent(String(username))}`, + let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; + return this.httpClient.put(`${this.configuration.basePath}${localVarPath}`, user, { context: localVarHttpContext, diff --git a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/configuration.ts b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/configuration.ts index 6fc0f80d973..5ea92c82cb6 100644 --- a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/configuration.ts +++ b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/configuration.ts @@ -1,4 +1,5 @@ import { HttpParameterCodec } from '@angular/common/http'; +import { Param } from './param'; export interface ConfigurationParameters { /** @@ -13,7 +14,18 @@ export interface ConfigurationParameters { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Override the default method for encoding path parameters in various + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam?: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -35,7 +47,18 @@ export class Configuration { accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; + /** + * Takes care of encoding query- and form-parameters. + */ encoder?: HttpParameterCodec; + /** + * Encoding of various path parameter + * styles. + *

+ * See {@link README.md} for more details + *

+ */ + encodeParam: (param: Param) => string; /** * The keys are the names in the securitySchemes section of the OpenAPI * document. They should map to the value used for authentication @@ -51,6 +74,12 @@ export class Configuration { this.basePath = configurationParameters.basePath; this.withCredentials = configurationParameters.withCredentials; this.encoder = configurationParameters.encoder; + if (configurationParameters.encodeParam) { + this.encodeParam = configurationParameters.encodeParam; + } + else { + this.encodeParam = param => this.defaultEncodeParam(param); + } if (configurationParameters.credentials) { this.credentials = configurationParameters.credentials; } @@ -138,4 +167,20 @@ export class Configuration { ? value() : value; } + + private defaultEncodeParam(param: Param): string { + // This implementation exists as fallback for missing configuration + // and for backwards compatibility to older typescript-angular generator versions. + // It only works for the 'simple' parameter style. + // Date-handling only works for the 'date-time' format. + // All other styles and Date-formats are probably handled incorrectly. + // + // But: if that's all you need (i.e.: the most common use-case): no need for customization! + + const value = param.dataFormat === 'date-time' + ? (param.value as Date).toISOString() + : param.value; + + return encodeURIComponent(String(value)); + } } diff --git a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/index.ts b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/index.ts index c312b70fa3e..104dd3d21e3 100644 --- a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/index.ts +++ b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/index.ts @@ -2,4 +2,5 @@ export * from './api/api'; export * from './model/models'; export * from './variables'; export * from './configuration'; -export * from './api.module'; \ No newline at end of file +export * from './api.module'; +export * from './param'; diff --git a/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/param.ts b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/param.ts new file mode 100644 index 00000000000..78a2d20a643 --- /dev/null +++ b/samples/client/petstore/typescript-angular-v14-provided-in-root/builds/default/param.ts @@ -0,0 +1,69 @@ +/** + * Standard parameter styles defined by OpenAPI spec + */ +export type StandardParamStyle = + | 'matrix' + | 'label' + | 'form' + | 'simple' + | 'spaceDelimited' + | 'pipeDelimited' + | 'deepObject' + ; + +/** + * The OpenAPI standard {@link StandardParamStyle}s may be extended by custom styles by the user. + */ +export type ParamStyle = StandardParamStyle | string; + +/** + * Standard parameter locations defined by OpenAPI spec + */ +export type ParamLocation = 'query' | 'header' | 'path' | 'cookie'; + +/** + * Standard types as defined in OpenAPI Specification: Data Types + */ +export type StandardDataType = + | "integer" + | "number" + | "boolean" + | "string" + | "object" + | "array" + ; + +/** + * Standard {@link DataType}s plus your own types/classes. + */ +export type DataType = StandardDataType | string; + +/** + * Standard formats as defined in OpenAPI Specification: Data Types + */ +export type StandardDataFormat = + | "int32" + | "int64" + | "float" + | "double" + | "byte" + | "binary" + | "date" + | "date-time" + | "password" + ; + +export type DataFormat = StandardDataFormat | string; + +/** + * The parameter to encode. + */ +export interface Param { + name: string; + value: unknown; + in: ParamLocation; + style: ParamStyle, + explode: boolean; + dataType: DataType; + dataFormat: DataFormat | undefined; +}