diff --git a/bin/configs/java-nullable-object-property.yaml b/bin/configs/java-nullable-object-property.yaml new file mode 100644 index 000000000000..399bfb4b8c9c --- /dev/null +++ b/bin/configs/java-nullable-object-property.yaml @@ -0,0 +1,8 @@ +generatorName: java +outputDir: samples/client/petstore/java/nullable-object-property +library: native +inputSpec: modules/openapi-generator/src/test/resources/3_0/issue_10593.yaml +templateDir: modules/openapi-generator/src/main/resources/Java +additionalProperties: + artifactId: java-nullable-property + hideGenerationTimestamp: "true" diff --git a/bin/configs/kotlin-nullable-object-property.yaml b/bin/configs/kotlin-nullable-object-property.yaml new file mode 100644 index 000000000000..9fcd65709648 --- /dev/null +++ b/bin/configs/kotlin-nullable-object-property.yaml @@ -0,0 +1,8 @@ +generatorName: kotlin +outputDir: samples/client/petstore/kotlin-nullable-object-propery +inputSpec: modules/openapi-generator/src/test/resources/3_0/issue_10593.yaml +templateDir: modules/openapi-generator/src/main/resources/kotlin-client +additionalProperties: + artifactId: nullable-object-property + serializableModel: "true" + nullableReturnType: "true" diff --git a/bin/configs/php-nullable-object-property.yaml b/bin/configs/php-nullable-object-property.yaml new file mode 100644 index 000000000000..c1063f8c72d0 --- /dev/null +++ b/bin/configs/php-nullable-object-property.yaml @@ -0,0 +1,4 @@ +generatorName: php +outputDir: samples/client/petstore/php/nullable-object-property-php +inputSpec: modules/openapi-generator/src/test/resources/3_0/issue_10593.yaml +templateDir: modules/openapi-generator/src/main/resources/php diff --git a/bin/configs/typescript-fetch-nullable-object-property.yaml b/bin/configs/typescript-fetch-nullable-object-property.yaml new file mode 100644 index 000000000000..ed87f9118fe7 --- /dev/null +++ b/bin/configs/typescript-fetch-nullable-object-property.yaml @@ -0,0 +1,4 @@ +generatorName: typescript-fetch +outputDir: samples/client/petstore/typescript-fetch/builds/nullable-object-property +inputSpec: modules/openapi-generator/src/test/resources/3_0/issue_10593.yaml +templateDir: modules/openapi-generator/src/main/resources/typescript-fetch diff --git a/docs/generators/typescript-angular.md b/docs/generators/typescript-angular.md index 7fde34c39a3f..89200adefb0c 100644 --- a/docs/generators/typescript-angular.md +++ b/docs/generators/typescript-angular.md @@ -84,6 +84,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • String
  • any
  • boolean
  • +
  • null
  • number
  • object
  • string
  • diff --git a/docs/generators/typescript-aurelia.md b/docs/generators/typescript-aurelia.md index 8d93a174bcc7..64015d7bad2f 100644 --- a/docs/generators/typescript-aurelia.md +++ b/docs/generators/typescript-aurelia.md @@ -68,6 +68,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • String
  • any
  • boolean
  • +
  • null
  • number
  • object
  • string
  • diff --git a/docs/generators/typescript-axios.md b/docs/generators/typescript-axios.md index 0850810c4d27..2db7dbc40e5c 100644 --- a/docs/generators/typescript-axios.md +++ b/docs/generators/typescript-axios.md @@ -74,6 +74,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • String
  • any
  • boolean
  • +
  • null
  • number
  • object
  • string
  • diff --git a/docs/generators/typescript-fetch.md b/docs/generators/typescript-fetch.md index 4901df93ed8d..df1b102ea7bf 100644 --- a/docs/generators/typescript-fetch.md +++ b/docs/generators/typescript-fetch.md @@ -75,6 +75,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • String
  • any
  • boolean
  • +
  • null
  • number
  • object
  • string
  • diff --git a/docs/generators/typescript-inversify.md b/docs/generators/typescript-inversify.md index bf1c2f146df3..975f719721f8 100644 --- a/docs/generators/typescript-inversify.md +++ b/docs/generators/typescript-inversify.md @@ -74,6 +74,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • String
  • any
  • boolean
  • +
  • null
  • number
  • object
  • string
  • diff --git a/docs/generators/typescript-jquery.md b/docs/generators/typescript-jquery.md index 3e0310ccfbe4..122997f10c3b 100644 --- a/docs/generators/typescript-jquery.md +++ b/docs/generators/typescript-jquery.md @@ -70,6 +70,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • String
  • any
  • boolean
  • +
  • null
  • number
  • object
  • string
  • diff --git a/docs/generators/typescript-nestjs.md b/docs/generators/typescript-nestjs.md index 38720fb9411e..8939b3305e8e 100644 --- a/docs/generators/typescript-nestjs.md +++ b/docs/generators/typescript-nestjs.md @@ -79,6 +79,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • String
  • any
  • boolean
  • +
  • null
  • number
  • object
  • string
  • diff --git a/docs/generators/typescript-node.md b/docs/generators/typescript-node.md index 28945f81c484..ca2a4b86e3b8 100644 --- a/docs/generators/typescript-node.md +++ b/docs/generators/typescript-node.md @@ -73,6 +73,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • String
  • any
  • boolean
  • +
  • null
  • number
  • object
  • string
  • diff --git a/docs/generators/typescript-redux-query.md b/docs/generators/typescript-redux-query.md index 67a6fffcb532..4339ff8d31f1 100644 --- a/docs/generators/typescript-redux-query.md +++ b/docs/generators/typescript-redux-query.md @@ -71,6 +71,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • String
  • any
  • boolean
  • +
  • null
  • number
  • object
  • string
  • diff --git a/docs/generators/typescript-rxjs.md b/docs/generators/typescript-rxjs.md index 24d906d8f23c..a7be36459538 100644 --- a/docs/generators/typescript-rxjs.md +++ b/docs/generators/typescript-rxjs.md @@ -71,6 +71,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • String
  • any
  • boolean
  • +
  • null
  • number
  • object
  • string
  • diff --git a/docs/generators/typescript.md b/docs/generators/typescript.md index be714cbd0969..f99fd66afc80 100644 --- a/docs/generators/typescript.md +++ b/docs/generators/typescript.md @@ -70,6 +70,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • String
  • any
  • boolean
  • +
  • null
  • number
  • string
  • diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 490ec670d6f7..b59cc153cb51 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -2203,6 +2203,10 @@ public String toAnyOfName(List names, ComposedSchema composedSchema) { * Otherwise, a name is constructed by creating a comma-separated list of all the names * of the oneOf schemas. * + * If the oneOf schema contains only one element and have the openapi 3.0 nullable flag, + * or one element and the openapi 3.1 'null' type, only this element is returned. + * + * * @param names List of names * @param composedSchema composed schema * @return name of the oneOf schema @@ -2213,6 +2217,12 @@ public String toOneOfName(List names, ComposedSchema composedSchema) { if (exts != null && exts.containsKey("x-one-of-name")) { return (String) exts.get("x-one-of-name"); } + if (Boolean.TRUE.equals(composedSchema.getNullable()) || ModelUtils.isNullableComposedSchema(composedSchema)) { + String singleType = names.stream().filter(p -> !p.equals("null")).findFirst().orElse(null); + if(singleType != null) { + return singleType; + } + } return "oneOf<" + String.join(",", names) + ">"; } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java index ea896fad5097..624b9a5e29fc 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java @@ -202,7 +202,7 @@ private boolean isModelNeeded(Schema schema, Set visitedSchemas) { if (m.getAnyOf() != null && !m.getAnyOf().isEmpty()) { return true; } - if (m.getOneOf() != null && !m.getOneOf().isEmpty()) { + if (m.getOneOf() != null && !m.getOneOf().isEmpty() && !isNullableOneOfComposedSchema(m)) { return true; } } @@ -352,7 +352,7 @@ private void gatherInlineModels(Schema schema, String modelPrefix) { } m.setAnyOf(newAnyOf); } - if (m.getOneOf() != null) { + if (m.getOneOf() != null && !isNullableOneOfComposedSchema(m)) { List newOneOf = new ArrayList(); for (Schema inner : m.getOneOf()) { String schemaName = resolveModelName(inner.getTitle(), modelPrefix + "_oneOf"); @@ -900,5 +900,17 @@ private String addSchemas(String name, Schema schema) { return name; } + private boolean isNullableOneOfComposedSchema(ComposedSchema schema) { + // OAS 3.0 oneOf with nullable attribute and single oneOf element + if (Boolean.TRUE.equals(schema.getNullable()) && schema.getOneOf() != null && schema.getOneOf().size() == 1) { + return true; + } + // OAS 3.1 nullable schema + if (ModelUtils.isNullableComposedSchema(schema)) { + return true; + } + + return false; + } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPhpCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPhpCodegen.java index 76390232004d..c0b745d3231c 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPhpCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPhpCodegen.java @@ -17,6 +17,7 @@ package org.openapitools.codegen.languages; import io.swagger.v3.oas.models.media.ArraySchema; +import io.swagger.v3.oas.models.media.ComposedSchema; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.StringSchema; import org.apache.commons.io.FilenameUtils; @@ -333,7 +334,24 @@ public String getTypeDeclaration(Schema p) { String type = super.getTypeDeclaration(p); return (!languageSpecificPrimitives.contains(type)) ? "\\" + modelPackage + "\\" + type : type; + } else if (p instanceof ComposedSchema) { + // Support nullable defined using oneOf construct + ComposedSchema composedSchema = (ComposedSchema)p; + Boolean isNullable = Boolean.TRUE.equals(p.getNullable()) + || ModelUtils.isNullableComposedSchema(composedSchema); + if (composedSchema.getOneOf() != null && isNullable) { + Schema inner = composedSchema + .getOneOf() + .stream() + .filter( + subSchema -> !ModelUtils.isNullType(subSchema) + ).findFirst().orElse(null); + if (inner != null) { + return this.getTypeDeclaration(inner); + } + } } + return super.getTypeDeclaration(p); } 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 4cac98e9ffe0..e92f99086f94 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 @@ -307,7 +307,8 @@ public AbstractTypeScriptClientCodegen() { "Error", "Map", "object", - "Set" + "Set", + "null" )); languageGenericTypes = new HashSet<>(Collections.singletonList( @@ -344,6 +345,7 @@ public AbstractTypeScriptClientCodegen() { typeMapping.put("URI", "string"); typeMapping.put("Error", "Error"); typeMapping.put("AnyType", "any"); + typeMapping.put("null", "null"); cliOptions.add(new CliOption(CodegenConstants.ENUM_NAME_SUFFIX, CodegenConstants.ENUM_NAME_SUFFIX_DESC).defaultValue(this.enumSuffix)); cliOptions.add(new CliOption(CodegenConstants.ENUM_PROPERTY_NAMING, CodegenConstants.ENUM_PROPERTY_NAMING_DESC).defaultValue(this.enumPropertyNaming.name())); @@ -1093,7 +1095,8 @@ public String toAnyOfName(List names, ComposedSchema composedSchema) { @Override public String toOneOfName(List names, ComposedSchema composedSchema) { List types = getTypesFromSchemas(composedSchema.getOneOf()); - + // Null is already handled by the isNullable flag + types.removeIf(p -> p.equals("null")); return String.join(" | ", types); } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java index 934fef92462c..bcdd0f8f4fd0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java @@ -144,7 +144,8 @@ public TypeScriptClientCodegen() { "File", "Error", "Map", - "Set" + "Set", + "null" )); languageGenericTypes = new HashSet<>(Arrays.asList( @@ -181,6 +182,7 @@ public TypeScriptClientCodegen() { typeMapping.put("UUID", "string"); typeMapping.put("Error", "Error"); typeMapping.put("AnyType", "any"); + typeMapping.put("null", "null"); cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package." + @@ -1521,7 +1523,8 @@ public String toAnyOfName(List names, ComposedSchema composedSchema) { @Override public String toOneOfName(List names, ComposedSchema composedSchema) { List types = getTypesFromSchemas(composedSchema.getOneOf()); - + // Null is already handled by the isNullable flag + types.removeIf(p -> p.equals("null")); return String.join(" | ", types); } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java index ef0b59a12bc0..ad2dd977d3ed 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java @@ -33,7 +33,6 @@ import io.swagger.v3.oas.models.responses.ApiResponses; import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.parser.core.models.ParseOptions; - import org.openapitools.codegen.config.CodegenConfigurator; import org.openapitools.codegen.config.GlobalSettings; import org.openapitools.codegen.model.ModelMap; @@ -3732,7 +3731,7 @@ public void testComposedPropertyTypes() { modelName = "ObjectWithComposedProperties"; CodegenModel m = codegen.fromModel(modelName, openAPI.getComponents().getSchemas().get(modelName)); /* TODO inline allOf schema are created as separate models and the following assumptions that - the properties are non-model are no longer valid and need to be revised + the properties are non-model are no longer valid and need to be revised assertTrue(m.vars.get(0).getIsMap()); assertTrue(m.vars.get(1).getIsNumber()); assertTrue(m.vars.get(2).getIsUnboundedInteger()); @@ -4245,4 +4244,34 @@ public void testFromPropertyRequiredAndOptional() { Assert.assertEquals(fooOptional.vars.get(0).name, "foo"); Assert.assertEquals(fooOptional.requiredVars.size(), 0); } + + @Test + public void testNullabelObjectProperties() { + DefaultCodegen codegen = new DefaultCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_10593.yaml"); + codegen.setOpenAPI(openAPI); + Schema schema = openAPI.getComponents().getSchemas().get("ModelWithNullableObjectProperty"); + + String propertyName; + CodegenProperty property; + + // openapi 3.0 nullable + propertyName = "propertyName30"; + property = codegen.fromProperty(propertyName, (Schema) schema.getProperties().get(propertyName)); + assertEquals(property.openApiType, "PropertyType"); + assertTrue(property.isNullable); + + // openapi 3.1 'null' + propertyName = "propertyName31"; + property = codegen.fromProperty(propertyName, (Schema) schema.getProperties().get(propertyName)); + assertEquals(property.openApiType, "PropertyType"); + assertTrue(property.isNullable); + + // Non regression on regular oneOf construct + propertyName = "nonNullableProperty"; + property = codegen.fromProperty(propertyName, (Schema) schema.getProperties().get(propertyName)); + assertEquals(property.openApiType, "ModelWithNullableObjectProperty_nonNullableProperty"); + assertFalse(property.isNullable); + // oneOf property resolve to any type and is set to nullable + } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/php/AbstractPhpCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/php/AbstractPhpCodegenTest.java index 5f7c52e54208..9bdc1d96c7b6 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/php/AbstractPhpCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/php/AbstractPhpCodegenTest.java @@ -34,6 +34,10 @@ import java.util.Arrays; import java.util.HashMap; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.AssertJUnit.assertFalse; + public class AbstractPhpCodegenTest { @Test @@ -166,6 +170,39 @@ public void testEnumPropertyWithDefaultValue() { Assert.assertEquals(cp1.getDefaultValue(), "'VALUE'"); } + @Test(description = "Issue #10593") + public void testModelWithNullableObjectProperty() { + final AbstractPhpCodegen codegen = new P_AbstractPhpCodegen(); + + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_10593.yaml"); + codegen.setOpenAPI(openAPI); + Schema schema = openAPI.getComponents().getSchemas().get("ModelWithNullableObjectProperty"); + + String propertyName; + CodegenProperty property; + + // regular property + propertyName = "propertyName"; + property = codegen.fromProperty(propertyName, (Schema) schema.getProperties().get(propertyName)); + assertEquals(property.openApiType, "PropertyType"); + assertFalse(property.isNullable); + assertEquals(property.dataType, "\\php\\Model\\PropertyType"); + + // openapi 3.0 nullable + propertyName = "propertyName30"; + property = codegen.fromProperty(propertyName, (Schema) schema.getProperties().get(propertyName)); + assertEquals(property.openApiType, "PropertyType"); + assertTrue(property.isNullable); + assertEquals(property.dataType, "\\php\\Model\\PropertyType"); + + // openapi 3.1 'null' + propertyName = "propertyName31"; + property = codegen.fromProperty(propertyName, (Schema) schema.getProperties().get(propertyName)); + assertEquals(property.openApiType, "PropertyType"); + assertTrue(property.isNullable); + assertEquals(property.dataType, "\\php\\Model\\PropertyType"); + } + private static class P_AbstractPhpCodegen extends AbstractPhpCodegen { @Override public CodegenType getTag() { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/AbstractTypeScriptClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/AbstractTypeScriptClientCodegenTest.java new file mode 100644 index 000000000000..25a68bedc2c5 --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/AbstractTypeScriptClientCodegenTest.java @@ -0,0 +1,64 @@ +package org.openapitools.codegen.typescript; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.media.Schema; + +import org.openapitools.codegen.CodegenProperty; +import org.openapitools.codegen.CodegenType; +import org.openapitools.codegen.DefaultCodegen; +import org.openapitools.codegen.TestUtils; +import org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen; +import org.testng.annotations.Test; + +import static org.junit.Assert.assertFalse; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +public class AbstractTypeScriptClientCodegenTest { + @Test + public void testNullabelObjectProperties() { + DefaultCodegen codegen = new P_AbstractTypeScriptClientCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_10593.yaml"); + codegen.setOpenAPI(openAPI); + Schema schema = openAPI.getComponents().getSchemas().get("ModelWithNullableObjectProperty"); + + String propertyName; + CodegenProperty property; + + // openapi 3.0 nullable + propertyName = "propertyName30"; + property = codegen.fromProperty(propertyName, (Schema) schema.getProperties().get(propertyName)); + assertEquals(property.openApiType, "PropertyType"); + assertTrue(property.isNullable); + + // openapi 3.1 'null' + propertyName = "propertyName31"; + property = codegen.fromProperty(propertyName, (Schema) schema.getProperties().get(propertyName)); + assertEquals(property.openApiType, "PropertyType"); + assertTrue(property.isNullable); + + // Non regression on regular oneOf construct + propertyName = "nonNullableProperty"; + property = codegen.fromProperty(propertyName, (Schema) schema.getProperties().get(propertyName)); + assertFalse(property.isNullable); + // assertEquals(property.openApiType, "string | number"); // Worked before #12104 + // oneOf property resolve to any type and is set to nullable + } + + private static class P_AbstractTypeScriptClientCodegen extends AbstractTypeScriptClientCodegen { + @Override + public CodegenType getTag() { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public String getHelp() { + return null; + } + } +} 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 925a6adcbc56..7b9b7c6e2f7e 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 @@ -7,6 +7,7 @@ import org.openapitools.codegen.CodegenModel; import org.openapitools.codegen.CodegenOperation; import org.openapitools.codegen.DefaultCodegen; +import org.openapitools.codegen.CodegenProperty; import org.openapitools.codegen.TestUtils; import org.openapitools.codegen.languages.TypeScriptClientCodegen; import org.openapitools.codegen.model.ModelMap; @@ -14,12 +15,15 @@ import org.openapitools.codegen.utils.ModelUtils; import org.testng.Assert; import org.testng.annotations.Test; - import java.io.File; import java.util.Collections; import java.util.List; import java.util.Map; +import static org.junit.Assert.assertFalse; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + @Test(groups = {TypeScriptGroups.TYPESCRIPT}) public class TypeScriptClientCodegenTest { @Test @@ -141,4 +145,34 @@ public void modelImportWithMappingTest() { Assert.assertEquals(tsImports.get(0).get("filename"), mappedName); Assert.assertEquals(tsImports.get(0).get("classname"), "ApiResponse"); } + + @Test + public void testNullabelObjectProperties() { + DefaultCodegen codegen = new TypeScriptClientCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_10593.yaml"); + codegen.setOpenAPI(openAPI); + Schema schema = openAPI.getComponents().getSchemas().get("ModelWithNullableObjectProperty"); + + String propertyName; + CodegenProperty property; + + // openapi 3.0 nullable + propertyName = "propertyName30"; + property = codegen.fromProperty(propertyName, (Schema) schema.getProperties().get(propertyName)); + assertEquals(property.openApiType, "PropertyType"); + assertTrue(property.isNullable); + + // openapi 3.1 'null' + propertyName = "propertyName31"; + property = codegen.fromProperty(propertyName, (Schema) schema.getProperties().get(propertyName)); + assertEquals(property.openApiType, "PropertyType"); + assertTrue(property.isNullable); + + // Non regression on regular oneOf construct + propertyName = "nonNullableProperty"; + property = codegen.fromProperty(propertyName, (Schema) schema.getProperties().get(propertyName)); + assertFalse(property.isNullable); + // assertEquals(property.openApiType, "string | number"); // Worked before #12104 + // oneOf property resolve to any type and is set to nullable + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_10593.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_10593.yaml new file mode 100644 index 000000000000..b7a9b0dc8348 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/issue_10593.yaml @@ -0,0 +1,46 @@ +openapi: 3.0.2 # This should be 3.1, but the parser does not accept that version yet. +info: + title: 'Title' + version: latest +paths: + '/': + get: + operationId: operation + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/ModelWithNullableObjectProperty' +components: + schemas: + ModelWithNullableObjectProperty: + properties: + propertyName: + $ref: '#/components/schemas/PropertyType' + propertyName30: + nullable: true + oneOf: + - $ref: '#/components/schemas/PropertyType' + propertyName31: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/PropertyType' + nonNullableProperty: + oneOf: + - type: string + - type: number + propertyWithNullAndTwoTypes: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/PropertyType' + - $ref: '#/components/schemas/OtherPropertyType' + PropertyType: + properties: + foo: + type: string + OtherPropertyType: + properties: + bar: + type: string diff --git a/samples/client/petstore/java/nullable-object-property/.github/workflows/maven.yml b/samples/client/petstore/java/nullable-object-property/.github/workflows/maven.yml new file mode 100644 index 000000000000..0d6b2f82a92c --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/.github/workflows/maven.yml @@ -0,0 +1,30 @@ +# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven +# +# This file is auto-generated by OpenAPI Generator (https://openapi-generator.tech) + +name: Java CI with Maven + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + +jobs: + build: + name: Build Title + runs-on: ubuntu-latest + strategy: + matrix: + java: [ '8' ] + steps: + - uses: actions/checkout@v2 + - name: Set up JDK + uses: actions/setup-java@v2 + with: + java-version: ${{ matrix.java }} + distribution: 'temurin' + cache: maven + - name: Build with Maven + run: mvn -B package --no-transfer-progress --file pom.xml diff --git a/samples/client/petstore/java/nullable-object-property/.gitignore b/samples/client/petstore/java/nullable-object-property/.gitignore new file mode 100644 index 000000000000..a530464afa1b --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/.gitignore @@ -0,0 +1,21 @@ +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# exclude jar for gradle wrapper +!gradle/wrapper/*.jar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +# build files +**/target +target +.gradle +build diff --git a/samples/client/petstore/java/nullable-object-property/.openapi-generator-ignore b/samples/client/petstore/java/nullable-object-property/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore/java/nullable-object-property/.openapi-generator/FILES b/samples/client/petstore/java/nullable-object-property/.openapi-generator/FILES new file mode 100644 index 000000000000..2f5c1d6d3deb --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/.openapi-generator/FILES @@ -0,0 +1,38 @@ +.github/workflows/maven.yml +.gitignore +.travis.yml +README.md +api/openapi.yaml +build.gradle +build.sbt +docs/DefaultApi.md +docs/ModelWithNullableObjectProperty.md +docs/ModelWithNullableObjectPropertyNonNullableProperty.md +docs/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md +docs/OtherPropertyType.md +docs/PropertyType.md +git_push.sh +gradle.properties +gradle/wrapper/gradle-wrapper.jar +gradle/wrapper/gradle-wrapper.properties +gradlew +gradlew.bat +pom.xml +settings.gradle +src/main/AndroidManifest.xml +src/main/java/org/openapitools/client/ApiClient.java +src/main/java/org/openapitools/client/ApiException.java +src/main/java/org/openapitools/client/ApiResponse.java +src/main/java/org/openapitools/client/Configuration.java +src/main/java/org/openapitools/client/JSON.java +src/main/java/org/openapitools/client/Pair.java +src/main/java/org/openapitools/client/RFC3339DateFormat.java +src/main/java/org/openapitools/client/ServerConfiguration.java +src/main/java/org/openapitools/client/ServerVariable.java +src/main/java/org/openapitools/client/api/DefaultApi.java +src/main/java/org/openapitools/client/model/AbstractOpenApiSchema.java +src/main/java/org/openapitools/client/model/ModelWithNullableObjectProperty.java +src/main/java/org/openapitools/client/model/ModelWithNullableObjectPropertyNonNullableProperty.java +src/main/java/org/openapitools/client/model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.java +src/main/java/org/openapitools/client/model/OtherPropertyType.java +src/main/java/org/openapitools/client/model/PropertyType.java diff --git a/samples/client/petstore/java/nullable-object-property/.openapi-generator/VERSION b/samples/client/petstore/java/nullable-object-property/.openapi-generator/VERSION new file mode 100644 index 000000000000..66672d4e9d31 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/.openapi-generator/VERSION @@ -0,0 +1 @@ +6.1.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/java/nullable-object-property/.travis.yml b/samples/client/petstore/java/nullable-object-property/.travis.yml new file mode 100644 index 000000000000..c94647479234 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/.travis.yml @@ -0,0 +1,16 @@ +# +# Generated by: https://openapi-generator.tech +# +language: java +jdk: + - oraclejdk11 +before_install: + # ensure gradlew has proper permission + - chmod a+x ./gradlew +script: + # test using maven + - mvn test + # uncomment below to test using gradle + # - gradle test + # uncomment below to test using sbt + # - sbt test diff --git a/samples/client/petstore/java/nullable-object-property/README.md b/samples/client/petstore/java/nullable-object-property/README.md new file mode 100644 index 000000000000..8352e08b36d6 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/README.md @@ -0,0 +1,133 @@ +# java-nullable-property + +Title + +- API version: latest + +No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + + +*Automatically generated by the [OpenAPI Generator](https://openapi-generator.tech)* + +## Requirements + +Building the API client library requires: + +1. Java 11+ +2. Maven/Gradle + +## Installation + +To install the API client library to your local Maven repository, simply execute: + +```shell +mvn clean install +``` + +To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: + +```shell +mvn clean deploy +``` + +Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information. + +### Maven users + +Add this dependency to your project's POM: + +```xml + + org.openapitools + java-nullable-property + latest + compile + +``` + +### Gradle users + +Add this dependency to your project's build file: + +```groovy +compile "org.openapitools:java-nullable-property:latest" +``` + +### Others + +At first generate the JAR by executing: + +```shell +mvn clean package +``` + +Then manually install the following JARs: + +- `target/java-nullable-property-latest.jar` +- `target/lib/*.jar` + +## Getting Started + +Please follow the [installation](#installation) instruction and execute the following Java code: + +```java + +import org.openapitools.client.*; +import org.openapitools.client.model.*; +import org.openapitools.client.api.DefaultApi; + +public class DefaultApiExample { + + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + // Configure clients using the `defaultClient` object, such as + // overriding the host and port, timeout, etc. + DefaultApi apiInstance = new DefaultApi(defaultClient); + try { + ModelWithNullableObjectProperty result = apiInstance.operation(); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DefaultApi#operation"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} + +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*DefaultApi* | [**operation**](docs/DefaultApi.md#operation) | **GET** / | +*DefaultApi* | [**operationWithHttpInfo**](docs/DefaultApi.md#operationWithHttpInfo) | **GET** / | + + +## Documentation for Models + + - [ModelWithNullableObjectProperty](docs/ModelWithNullableObjectProperty.md) + - [ModelWithNullableObjectPropertyNonNullableProperty](docs/ModelWithNullableObjectPropertyNonNullableProperty.md) + - [ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes](docs/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md) + - [OtherPropertyType](docs/OtherPropertyType.md) + - [PropertyType](docs/PropertyType.md) + + +## Documentation for Authorization + +All endpoints do not require authorization. +Authentication schemes defined for the API: + +## Recommendation + +It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues. +However, the instances of the api clients created from the `ApiClient` are thread-safe and can be re-used. + +## Author + + + diff --git a/samples/client/petstore/java/nullable-object-property/api/openapi.yaml b/samples/client/petstore/java/nullable-object-property/api/openapi.yaml new file mode 100644 index 000000000000..2076b5cb3ebe --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/api/openapi.yaml @@ -0,0 +1,63 @@ +openapi: 3.0.2 +info: + title: Title + version: latest +servers: +- url: / +paths: + /: + get: + operationId: operation + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/ModelWithNullableObjectProperty' + description: Success + x-accepts: application/json +components: + schemas: + ModelWithNullableObjectProperty: + example: + propertyName: + foo: foo + nonNullableProperty: null + propertyName31: "" + propertyName30: "" + propertyWithNullAndTwoTypes: null + properties: + propertyName: + $ref: '#/components/schemas/PropertyType' + propertyName30: + nullable: true + oneOf: + - $ref: '#/components/schemas/PropertyType' + propertyName31: + oneOf: + - type: "null" + - $ref: '#/components/schemas/PropertyType' + nonNullableProperty: + $ref: '#/components/schemas/ModelWithNullableObjectProperty_nonNullableProperty' + propertyWithNullAndTwoTypes: + $ref: '#/components/schemas/ModelWithNullableObjectProperty_propertyWithNullAndTwoTypes' + PropertyType: + example: + foo: foo + properties: + foo: + type: string + OtherPropertyType: + properties: + bar: + type: string + ModelWithNullableObjectProperty_nonNullableProperty: + oneOf: + - type: string + - type: number + ModelWithNullableObjectProperty_propertyWithNullAndTwoTypes: + oneOf: + - type: "null" + - $ref: '#/components/schemas/PropertyType' + - $ref: '#/components/schemas/OtherPropertyType' + diff --git a/samples/client/petstore/java/nullable-object-property/build.gradle b/samples/client/petstore/java/nullable-object-property/build.gradle new file mode 100644 index 000000000000..c3af3bdb83dc --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/build.gradle @@ -0,0 +1,81 @@ +apply plugin: 'idea' +apply plugin: 'eclipse' + +group = 'org.openapitools' +version = 'latest' + +buildscript { + repositories { + mavenCentral() + } +} + +repositories { + mavenCentral() +} + +apply plugin: 'java' +apply plugin: 'maven-publish' + +sourceCompatibility = JavaVersion.VERSION_11 +targetCompatibility = JavaVersion.VERSION_11 + +// Some text from the schema is copy pasted into the source files as UTF-8 +// but the default still seems to be to use platform encoding +tasks.withType(JavaCompile) { + configure(options) { + options.encoding = 'UTF-8' + } +} +javadoc { + options.encoding = 'UTF-8' +} + +publishing { + publications { + maven(MavenPublication) { + artifactId = 'java-nullable-property' + from components.java + } + } +} + +task execute(type:JavaExec) { + main = System.getProperty('mainClass') + classpath = sourceSets.main.runtimeClasspath +} + +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from sourceSets.main.allSource +} + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir +} + +artifacts { + archives sourcesJar + archives javadocJar +} + + +ext { + swagger_annotations_version = "1.5.22" + jackson_version = "2.13.0" + jakarta_annotation_version = "1.3.5" + junit_version = "4.13.2" +} + +dependencies { + implementation "io.swagger:swagger-annotations:$swagger_annotations_version" + implementation "com.google.code.findbugs:jsr305:3.0.2" + implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" + implementation "org.openapitools:jackson-databind-nullable:0.2.1" + implementation "jakarta.annotation:jakarta.annotation-api:$jakarta_annotation_version" + testImplementation "junit:junit:$junit_version" +} diff --git a/samples/client/petstore/java/nullable-object-property/build.sbt b/samples/client/petstore/java/nullable-object-property/build.sbt new file mode 100644 index 000000000000..464090415c47 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/build.sbt @@ -0,0 +1 @@ +# TODO diff --git a/samples/client/petstore/java/nullable-object-property/docs/DefaultApi.md b/samples/client/petstore/java/nullable-object-property/docs/DefaultApi.md new file mode 100644 index 000000000000..7e2dda03d168 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/docs/DefaultApi.md @@ -0,0 +1,132 @@ +# DefaultApi + +All URIs are relative to *http://localhost* + +| Method | HTTP request | Description | +|------------- | ------------- | -------------| +| [**operation**](DefaultApi.md#operation) | **GET** / | | +| [**operationWithHttpInfo**](DefaultApi.md#operationWithHttpInfo) | **GET** / | | + + + +## operation + +> ModelWithNullableObjectProperty operation() + + + +### Example + +```java +// Import classes: +import org.openapitools.client.ApiClient; +import org.openapitools.client.ApiException; +import org.openapitools.client.Configuration; +import org.openapitools.client.models.*; +import org.openapitools.client.api.DefaultApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("http://localhost"); + + DefaultApi apiInstance = new DefaultApi(defaultClient); + try { + ModelWithNullableObjectProperty result = apiInstance.operation(); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling DefaultApi#operation"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +[**ModelWithNullableObjectProperty**](ModelWithNullableObjectProperty.md) + + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Success | - | + +## operationWithHttpInfo + +> ApiResponse operation operationWithHttpInfo() + + + +### Example + +```java +// Import classes: +import org.openapitools.client.ApiClient; +import org.openapitools.client.ApiException; +import org.openapitools.client.ApiResponse; +import org.openapitools.client.Configuration; +import org.openapitools.client.models.*; +import org.openapitools.client.api.DefaultApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("http://localhost"); + + DefaultApi apiInstance = new DefaultApi(defaultClient); + try { + ApiResponse response = apiInstance.operationWithHttpInfo(); + System.out.println("Status code: " + response.getStatusCode()); + System.out.println("Response headers: " + response.getHeaders()); + System.out.println("Response body: " + response.getData()); + } catch (ApiException e) { + System.err.println("Exception when calling DefaultApi#operation"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Response headers: " + e.getResponseHeaders()); + System.err.println("Reason: " + e.getResponseBody()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +ApiResponse<[**ModelWithNullableObjectProperty**](ModelWithNullableObjectProperty.md)> + + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Success | - | + diff --git a/samples/client/petstore/java/nullable-object-property/docs/ModelWithNullableObjectProperty.md b/samples/client/petstore/java/nullable-object-property/docs/ModelWithNullableObjectProperty.md new file mode 100644 index 000000000000..0127a8eec9e6 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/docs/ModelWithNullableObjectProperty.md @@ -0,0 +1,17 @@ + + +# ModelWithNullableObjectProperty + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**propertyName** | [**PropertyType**](PropertyType.md) | | [optional] | +|**propertyName30** | [**PropertyType**](PropertyType.md) | | [optional] | +|**propertyName31** | [**PropertyType**](PropertyType.md) | | [optional] | +|**nonNullableProperty** | [**ModelWithNullableObjectPropertyNonNullableProperty**](ModelWithNullableObjectPropertyNonNullableProperty.md) | | [optional] | +|**propertyWithNullAndTwoTypes** | [**ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes**](ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md) | | [optional] | + + + diff --git a/samples/client/petstore/java/nullable-object-property/docs/ModelWithNullableObjectPropertyNonNullableProperty.md b/samples/client/petstore/java/nullable-object-property/docs/ModelWithNullableObjectPropertyNonNullableProperty.md new file mode 100644 index 000000000000..ff959bf0530f --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/docs/ModelWithNullableObjectPropertyNonNullableProperty.md @@ -0,0 +1,37 @@ + + +# ModelWithNullableObjectPropertyNonNullableProperty + +## oneOf schemas +* [BigDecimal](BigDecimal.md) +* [String](String.md) + +## Example +```java +// Import classes: +import org.openapitools.client.model.ModelWithNullableObjectPropertyNonNullableProperty; +import org.openapitools.client.model.BigDecimal; +import org.openapitools.client.model.String; + +public class Example { + public static void main(String[] args) { + ModelWithNullableObjectPropertyNonNullableProperty exampleModelWithNullableObjectPropertyNonNullableProperty = new ModelWithNullableObjectPropertyNonNullableProperty(); + + // create a new BigDecimal + BigDecimal exampleBigDecimal = new BigDecimal(); + // set ModelWithNullableObjectPropertyNonNullableProperty to BigDecimal + exampleModelWithNullableObjectPropertyNonNullableProperty.setActualInstance(exampleBigDecimal); + // to get back the BigDecimal set earlier + BigDecimal testBigDecimal = (BigDecimal) exampleModelWithNullableObjectPropertyNonNullableProperty.getActualInstance(); + + // create a new String + String exampleString = new String(); + // set ModelWithNullableObjectPropertyNonNullableProperty to String + exampleModelWithNullableObjectPropertyNonNullableProperty.setActualInstance(exampleString); + // to get back the String set earlier + String testString = (String) exampleModelWithNullableObjectPropertyNonNullableProperty.getActualInstance(); + } +} +``` + + diff --git a/samples/client/petstore/java/nullable-object-property/docs/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md b/samples/client/petstore/java/nullable-object-property/docs/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md new file mode 100644 index 000000000000..2a6c7ad70944 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/docs/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md @@ -0,0 +1,39 @@ + + +# ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes + +## oneOf schemas +* [OtherPropertyType](OtherPropertyType.md) +* [PropertyType](PropertyType.md) + +NOTE: this class is nullable. + +## Example +```java +// Import classes: +import org.openapitools.client.model.ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes; +import org.openapitools.client.model.OtherPropertyType; +import org.openapitools.client.model.PropertyType; + +public class Example { + public static void main(String[] args) { + ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes exampleModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes = new ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes(); + + // create a new OtherPropertyType + OtherPropertyType exampleOtherPropertyType = new OtherPropertyType(); + // set ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes to OtherPropertyType + exampleModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.setActualInstance(exampleOtherPropertyType); + // to get back the OtherPropertyType set earlier + OtherPropertyType testOtherPropertyType = (OtherPropertyType) exampleModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.getActualInstance(); + + // create a new PropertyType + PropertyType examplePropertyType = new PropertyType(); + // set ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes to PropertyType + exampleModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.setActualInstance(examplePropertyType); + // to get back the PropertyType set earlier + PropertyType testPropertyType = (PropertyType) exampleModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.getActualInstance(); + } +} +``` + + diff --git a/samples/client/petstore/java/nullable-object-property/docs/OtherPropertyType.md b/samples/client/petstore/java/nullable-object-property/docs/OtherPropertyType.md new file mode 100644 index 000000000000..f10876a3a792 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/docs/OtherPropertyType.md @@ -0,0 +1,13 @@ + + +# OtherPropertyType + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**bar** | **String** | | [optional] | + + + diff --git a/samples/client/petstore/java/nullable-object-property/docs/PropertyType.md b/samples/client/petstore/java/nullable-object-property/docs/PropertyType.md new file mode 100644 index 000000000000..55357b02ada1 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/docs/PropertyType.md @@ -0,0 +1,13 @@ + + +# PropertyType + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**foo** | **String** | | [optional] | + + + diff --git a/samples/client/petstore/java/nullable-object-property/git_push.sh b/samples/client/petstore/java/nullable-object-property/git_push.sh new file mode 100644 index 000000000000..f53a75d4fabe --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/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="github.com" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/samples/client/petstore/java/nullable-object-property/gradle.properties b/samples/client/petstore/java/nullable-object-property/gradle.properties new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/samples/client/petstore/java/nullable-object-property/gradle/wrapper/gradle-wrapper.jar b/samples/client/petstore/java/nullable-object-property/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000000..7454180f2ae8 Binary files /dev/null and b/samples/client/petstore/java/nullable-object-property/gradle/wrapper/gradle-wrapper.jar differ diff --git a/samples/client/petstore/java/nullable-object-property/gradle/wrapper/gradle-wrapper.properties b/samples/client/petstore/java/nullable-object-property/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..ffed3a254e91 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/samples/client/petstore/java/nullable-object-property/gradlew b/samples/client/petstore/java/nullable-object-property/gradlew new file mode 100644 index 000000000000..005bcde04284 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# 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. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/samples/client/petstore/java/nullable-object-property/gradlew.bat b/samples/client/petstore/java/nullable-object-property/gradlew.bat new file mode 100644 index 000000000000..6a68175eb70f --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS=-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/samples/client/petstore/java/nullable-object-property/pom.xml b/samples/client/petstore/java/nullable-object-property/pom.xml new file mode 100644 index 000000000000..19846be0cbe8 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/pom.xml @@ -0,0 +1,222 @@ + + 4.0.0 + org.openapitools + java-nullable-property + jar + java-nullable-property + latest + https://github.com/openapitools/openapi-generator + OpenAPI Java + + scm:git:git@github.com:openapitools/openapi-generator.git + scm:git:git@github.com:openapitools/openapi-generator.git + https://github.com/openapitools/openapi-generator + + + + + Unlicense + http://unlicense.org + repo + + + + + + OpenAPI-Generator Contributors + team@openapitools.org + OpenAPITools.org + http://openapitools.org + + + + + + + maven-enforcer-plugin + 3.0.0-M1 + + + enforce-maven + + enforce + + + + + 3 + + + 11 + + + + + + + + maven-surefire-plugin + 3.0.0-M3 + + + conf/log4j.properties + + -Xms512m -Xmx1500m + methods + 10 + + + + maven-dependency-plugin + 3.1.1 + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.2 + + + + test-jar + + + + + + + + maven-compiler-plugin + 3.8.1 + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.3.2 + + + attach-javadocs + + jar + + + + + + maven-source-plugin + 3.1.0 + + + attach-sources + + jar-no-fork + + + + + + + + + + sign-artifacts + + + + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + io.swagger + swagger-annotations + ${swagger-annotations-version} + + + + + com.fasterxml.jackson.core + jackson-core + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson-version} + + + org.openapitools + jackson-databind-nullable + ${jackson-databind-nullable-version} + + + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + jakarta.annotation + jakarta.annotation-api + ${jakarta-annotation-version} + provided + + + + + junit + junit + ${junit-version} + test + + + + + UTF-8 + 1.5.22 + 11 + 11 + 2.13.0 + 0.2.3 + 1.3.5 + 4.13.2 + + diff --git a/samples/client/petstore/java/nullable-object-property/settings.gradle b/samples/client/petstore/java/nullable-object-property/settings.gradle new file mode 100644 index 000000000000..f0594adf6cb4 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/settings.gradle @@ -0,0 +1 @@ +rootProject.name = "java-nullable-property" \ No newline at end of file diff --git a/samples/client/petstore/java/nullable-object-property/src/main/AndroidManifest.xml b/samples/client/petstore/java/nullable-object-property/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..54fbcb3da1e8 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ApiClient.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ApiClient.java new file mode 100644 index 000000000000..65cda6782190 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ApiClient.java @@ -0,0 +1,456 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package org.openapitools.client; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.openapitools.jackson.nullable.JsonNullableModule; + +import java.io.InputStream; +import java.net.URI; +import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpConnectTimeoutException; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.StringJoiner; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + * Configuration and utility class for API clients. + * + *

    This class can be constructed and modified, then used to instantiate the + * various API classes. The API classes use the settings in this class to + * configure themselves, but otherwise do not store a link to this class.

    + * + *

    This class is mutable and not synchronized, so it is not thread-safe. + * The API classes generated from this are immutable and thread-safe.

    + * + *

    The setter methods of this class return the current object to facilitate + * a fluent style of configuration.

    + */ +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ApiClient { + + private HttpClient.Builder builder; + private ObjectMapper mapper; + private String scheme; + private String host; + private int port; + private String basePath; + private Consumer interceptor; + private Consumer> responseInterceptor; + private Consumer> asyncResponseInterceptor; + private Duration readTimeout; + private Duration connectTimeout; + + private static String valueToString(Object value) { + if (value == null) { + return ""; + } + if (value instanceof OffsetDateTime) { + return ((OffsetDateTime) value).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } + return value.toString(); + } + + /** + * URL encode a string in the UTF-8 encoding. + * + * @param s String to encode. + * @return URL-encoded representation of the input string. + */ + public static String urlEncode(String s) { + return URLEncoder.encode(s, UTF_8).replaceAll("\\+", "%20"); + } + + /** + * Convert a URL query name/value parameter to a list of encoded {@link Pair} + * objects. + * + *

    The value can be null, in which case an empty list is returned.

    + * + * @param name The query name parameter. + * @param value The query value, which may not be a collection but may be + * null. + * @return A singleton list of the {@link Pair} objects representing the input + * parameters, which is encoded for use in a URL. If the value is null, an + * empty list is returned. + */ + public static List parameterToPairs(String name, Object value) { + if (name == null || name.isEmpty() || value == null) { + return Collections.emptyList(); + } + return Collections.singletonList(new Pair(urlEncode(name), urlEncode(valueToString(value)))); + } + + /** + * Convert a URL query name/collection parameter to a list of encoded + * {@link Pair} objects. + * + * @param collectionFormat The swagger collectionFormat string (csv, tsv, etc). + * @param name The query name parameter. + * @param values A collection of values for the given query name, which may be + * null. + * @return A list of {@link Pair} objects representing the input parameters, + * which is encoded for use in a URL. If the values collection is null, an + * empty list is returned. + */ + public static List parameterToPairs( + String collectionFormat, String name, Collection values) { + if (name == null || name.isEmpty() || values == null || values.isEmpty()) { + return Collections.emptyList(); + } + + // get the collection format (default: csv) + String format = collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat; + + // create the params based on the collection format + if ("multi".equals(format)) { + return values.stream() + .map(value -> new Pair(urlEncode(name), urlEncode(valueToString(value)))) + .collect(Collectors.toList()); + } + + String delimiter; + switch(format) { + case "csv": + delimiter = urlEncode(","); + break; + case "ssv": + delimiter = urlEncode(" "); + break; + case "tsv": + delimiter = urlEncode("\t"); + break; + case "pipes": + delimiter = urlEncode("|"); + break; + default: + throw new IllegalArgumentException("Illegal collection format: " + collectionFormat); + } + + StringJoiner joiner = new StringJoiner(delimiter); + for (Object value : values) { + joiner.add(urlEncode(valueToString(value))); + } + + return Collections.singletonList(new Pair(urlEncode(name), joiner.toString())); + } + + /** + * Create an instance of ApiClient. + */ + public ApiClient() { + this.builder = createDefaultHttpClientBuilder(); + this.mapper = createDefaultObjectMapper(); + updateBaseUri(getDefaultBaseUri()); + interceptor = null; + readTimeout = null; + connectTimeout = null; + responseInterceptor = null; + asyncResponseInterceptor = null; + } + + /** + * Create an instance of ApiClient. + * + * @param builder Http client builder. + * @param mapper Object mapper. + * @param baseUri Base URI + */ + public ApiClient(HttpClient.Builder builder, ObjectMapper mapper, String baseUri) { + this.builder = builder; + this.mapper = mapper; + updateBaseUri(baseUri != null ? baseUri : getDefaultBaseUri()); + interceptor = null; + readTimeout = null; + connectTimeout = null; + responseInterceptor = null; + asyncResponseInterceptor = null; + } + + protected ObjectMapper createDefaultObjectMapper() { + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); + mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); + mapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE); + mapper.registerModule(new JavaTimeModule()); + mapper.registerModule(new JsonNullableModule()); + return mapper; + } + + protected String getDefaultBaseUri() { + return "http://localhost"; + } + + protected HttpClient.Builder createDefaultHttpClientBuilder() { + return HttpClient.newBuilder(); + } + + public void updateBaseUri(String baseUri) { + URI uri = URI.create(baseUri); + scheme = uri.getScheme(); + host = uri.getHost(); + port = uri.getPort(); + basePath = uri.getRawPath(); + } + + /** + * Set a custom {@link HttpClient.Builder} object to use when creating the + * {@link HttpClient} that is used by the API client. + * + * @param builder Custom client builder. + * @return This object. + */ + public ApiClient setHttpClientBuilder(HttpClient.Builder builder) { + this.builder = builder; + return this; + } + + /** + * Get an {@link HttpClient} based on the current {@link HttpClient.Builder}. + * + *

    The returned object is immutable and thread-safe.

    + * + * @return The HTTP client. + */ + public HttpClient getHttpClient() { + return builder.build(); + } + + /** + * Set a custom {@link ObjectMapper} to serialize and deserialize the request + * and response bodies. + * + * @param mapper Custom object mapper. + * @return This object. + */ + public ApiClient setObjectMapper(ObjectMapper mapper) { + this.mapper = mapper; + return this; + } + + /** + * Get a copy of the current {@link ObjectMapper}. + * + * @return A copy of the current object mapper. + */ + public ObjectMapper getObjectMapper() { + return mapper.copy(); + } + + /** + * Set a custom host name for the target service. + * + * @param host The host name of the target service. + * @return This object. + */ + public ApiClient setHost(String host) { + this.host = host; + return this; + } + + /** + * Set a custom port number for the target service. + * + * @param port The port of the target service. Set this to -1 to reset the + * value to the default for the scheme. + * @return This object. + */ + public ApiClient setPort(int port) { + this.port = port; + return this; + } + + /** + * Set a custom base path for the target service, for example '/v2'. + * + * @param basePath The base path against which the rest of the path is + * resolved. + * @return This object. + */ + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Get the base URI to resolve the endpoint paths against. + * + * @return The complete base URI that the rest of the API parameters are + * resolved against. + */ + public String getBaseUri() { + return scheme + "://" + host + (port == -1 ? "" : ":" + port) + basePath; + } + + /** + * Set a custom scheme for the target service, for example 'https'. + * + * @param scheme The scheme of the target service + * @return This object. + */ + public ApiClient setScheme(String scheme){ + this.scheme = scheme; + return this; + } + + /** + * Set a custom request interceptor. + * + *

    A request interceptor is a mechanism for altering each request before it + * is sent. After the request has been fully configured but not yet built, the + * request builder is passed into this function for further modification, + * after which it is sent out.

    + * + *

    This is useful for altering the requests in a custom manner, such as + * adding headers. It could also be used for logging and monitoring.

    + * + * @param interceptor A function invoked before creating each request. A value + * of null resets the interceptor to a no-op. + * @return This object. + */ + public ApiClient setRequestInterceptor(Consumer interceptor) { + this.interceptor = interceptor; + return this; + } + + /** + * Get the custom interceptor. + * + * @return The custom interceptor that was set, or null if there isn't any. + */ + public Consumer getRequestInterceptor() { + return interceptor; + } + + /** + * Set a custom response interceptor. + * + *

    This is useful for logging, monitoring or extraction of header variables

    + * + * @param interceptor A function invoked before creating each request. A value + * of null resets the interceptor to a no-op. + * @return This object. + */ + public ApiClient setResponseInterceptor(Consumer> interceptor) { + this.responseInterceptor = interceptor; + return this; + } + + /** + * Get the custom response interceptor. + * + * @return The custom interceptor that was set, or null if there isn't any. + */ + public Consumer> getResponseInterceptor() { + return responseInterceptor; + } + + /** + * Set a custom async response interceptor. Use this interceptor when asyncNative is set to 'true'. + * + *

    This is useful for logging, monitoring or extraction of header variables

    + * + * @param interceptor A function invoked before creating each request. A value + * of null resets the interceptor to a no-op. + * @return This object. + */ + public ApiClient setAsyncResponseInterceptor(Consumer> interceptor) { + this.asyncResponseInterceptor = interceptor; + return this; + } + + /** + * Get the custom async response interceptor. Use this interceptor when asyncNative is set to 'true'. + * + * @return The custom interceptor that was set, or null if there isn't any. + */ + public Consumer> getAsyncResponseInterceptor() { + return asyncResponseInterceptor; + } + + /** + * Set the read timeout for the http client. + * + *

    This is the value used by default for each request, though it can be + * overridden on a per-request basis with a request interceptor.

    + * + * @param readTimeout The read timeout used by default by the http client. + * Setting this value to null resets the timeout to an + * effectively infinite value. + * @return This object. + */ + public ApiClient setReadTimeout(Duration readTimeout) { + this.readTimeout = readTimeout; + return this; + } + + /** + * Get the read timeout that was set. + * + * @return The read timeout, or null if no timeout was set. Null represents + * an infinite wait time. + */ + public Duration getReadTimeout() { + return readTimeout; + } + /** + * Sets the connect timeout (in milliseconds) for the http client. + * + *

    In the case where a new connection needs to be established, if + * the connection cannot be established within the given {@code + * duration}, then {@link HttpClient#send(HttpRequest,BodyHandler) + * HttpClient::send} throws an {@link HttpConnectTimeoutException}, or + * {@link HttpClient#sendAsync(HttpRequest,BodyHandler) + * HttpClient::sendAsync} completes exceptionally with an + * {@code HttpConnectTimeoutException}. If a new connection does not + * need to be established, for example if a connection can be reused + * from a previous request, then this timeout duration has no effect. + * + * @param connectTimeout connection timeout in milliseconds + * + * @return This object. + */ + public ApiClient setConnectTimeout(Duration connectTimeout) { + this.connectTimeout = connectTimeout; + this.builder.connectTimeout(connectTimeout); + return this; + } + + /** + * Get connection timeout (in milliseconds). + * + * @return Timeout in milliseconds + */ + public Duration getConnectTimeout() { + return connectTimeout; + } +} diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ApiException.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ApiException.java new file mode 100644 index 000000000000..02265184f519 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ApiException.java @@ -0,0 +1,90 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + +import java.net.http.HttpHeaders; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ApiException extends Exception { + private int code = 0; + private HttpHeaders responseHeaders = null; + private String responseBody = null; + + public ApiException() {} + + public ApiException(Throwable throwable) { + super(throwable); + } + + public ApiException(String message) { + super(message); + } + + public ApiException(String message, Throwable throwable, int code, HttpHeaders responseHeaders, String responseBody) { + super(message, throwable); + this.code = code; + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + } + + public ApiException(String message, int code, HttpHeaders responseHeaders, String responseBody) { + this(message, (Throwable) null, code, responseHeaders, responseBody); + } + + public ApiException(String message, Throwable throwable, int code, HttpHeaders responseHeaders) { + this(message, throwable, code, responseHeaders, null); + } + + public ApiException(int code, HttpHeaders responseHeaders, String responseBody) { + this((String) null, (Throwable) null, code, responseHeaders, responseBody); + } + + public ApiException(int code, String message) { + super(message); + this.code = code; + } + + public ApiException(int code, String message, HttpHeaders responseHeaders, String responseBody) { + this(code, message); + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + } + + /** + * Get the HTTP status code. + * + * @return HTTP status code + */ + public int getCode() { + return code; + } + + /** + * Get the HTTP response headers. + * + * @return Headers as an HttpHeaders object + */ + public HttpHeaders getResponseHeaders() { + return responseHeaders; + } + + /** + * Get the HTTP response body. + * + * @return Response body in the form of string + */ + public String getResponseBody() { + return responseBody; + } +} diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ApiResponse.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ApiResponse.java new file mode 100644 index 000000000000..9de23d4fb4f6 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ApiResponse.java @@ -0,0 +1,59 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + +import java.util.List; +import java.util.Map; + +/** + * API response returned by API call. + * + * @param The type of data that is deserialized from response body + */ +public class ApiResponse { + final private int statusCode; + final private Map> headers; + final private T data; + + /** + * @param statusCode The status code of HTTP response + * @param headers The headers of HTTP response + */ + public ApiResponse(int statusCode, Map> headers) { + this(statusCode, headers, null); + } + + /** + * @param statusCode The status code of HTTP response + * @param headers The headers of HTTP response + * @param data The object deserialized from response bod + */ + public ApiResponse(int statusCode, Map> headers, T data) { + this.statusCode = statusCode; + this.headers = headers; + this.data = data; + } + + public int getStatusCode() { + return statusCode; + } + + public Map> getHeaders() { + return headers; + } + + public T getData() { + return data; + } +} diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/Configuration.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/Configuration.java new file mode 100644 index 000000000000..d79ed947b233 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/Configuration.java @@ -0,0 +1,39 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Configuration { + private static ApiClient defaultApiClient = new ApiClient(); + + /** + * Get the default API client, which would be used when creating API + * instances without providing an API client. + * + * @return Default API client + */ + public static ApiClient getDefaultApiClient() { + return defaultApiClient; + } + + /** + * Set the default API client, which would be used when creating API + * instances without providing an API client. + * + * @param apiClient API client + */ + public static void setDefaultApiClient(ApiClient apiClient) { + defaultApiClient = apiClient; + } +} diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/JSON.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/JSON.java new file mode 100644 index 000000000000..7a69ba9d61d5 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/JSON.java @@ -0,0 +1,248 @@ +package org.openapitools.client; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.databind.*; +import org.openapitools.jackson.nullable.JsonNullableModule; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.openapitools.client.model.*; + +import java.text.DateFormat; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class JSON { + private ObjectMapper mapper; + + public JSON() { + mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + mapper.configure(MapperFeature.ALLOW_COERCION_OF_SCALARS, false); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); + mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, true); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); + mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); + mapper.setDateFormat(new RFC3339DateFormat()); + mapper.registerModule(new JavaTimeModule()); + JsonNullableModule jnm = new JsonNullableModule(); + mapper.registerModule(jnm); + } + + /** + * Set the date format for JSON (de)serialization with Date properties. + * + * @param dateFormat Date format + */ + public void setDateFormat(DateFormat dateFormat) { + mapper.setDateFormat(dateFormat); + } + + /** + * Get the object mapper + * + * @return object mapper + */ + public ObjectMapper getMapper() { return mapper; } + + /** + * Returns the target model class that should be used to deserialize the input data. + * The discriminator mappings are used to determine the target model class. + * + * @param node The input data. + * @param modelClass The class that contains the discriminator mappings. + * + * @return the target model class. + */ + public static Class getClassForElement(JsonNode node, Class modelClass) { + ClassDiscriminatorMapping cdm = modelDiscriminators.get(modelClass); + if (cdm != null) { + return cdm.getClassForElement(node, new HashSet>()); + } + return null; + } + + /** + * Helper class to register the discriminator mappings. + */ + private static class ClassDiscriminatorMapping { + // The model class name. + Class modelClass; + // The name of the discriminator property. + String discriminatorName; + // The discriminator mappings for a model class. + Map> discriminatorMappings; + + // Constructs a new class discriminator. + ClassDiscriminatorMapping(Class cls, String propertyName, Map> mappings) { + modelClass = cls; + discriminatorName = propertyName; + discriminatorMappings = new HashMap>(); + if (mappings != null) { + discriminatorMappings.putAll(mappings); + } + } + + // Return the name of the discriminator property for this model class. + String getDiscriminatorPropertyName() { + return discriminatorName; + } + + // Return the discriminator value or null if the discriminator is not + // present in the payload. + String getDiscriminatorValue(JsonNode node) { + // Determine the value of the discriminator property in the input data. + if (discriminatorName != null) { + // Get the value of the discriminator property, if present in the input payload. + node = node.get(discriminatorName); + if (node != null && node.isValueNode()) { + String discrValue = node.asText(); + if (discrValue != null) { + return discrValue; + } + } + } + return null; + } + + /** + * Returns the target model class that should be used to deserialize the input data. + * This function can be invoked for anyOf/oneOf composed models with discriminator mappings. + * The discriminator mappings are used to determine the target model class. + * + * @param node The input data. + * @param visitedClasses The set of classes that have already been visited. + * + * @return the target model class. + */ + Class getClassForElement(JsonNode node, Set> visitedClasses) { + if (visitedClasses.contains(modelClass)) { + // Class has already been visited. + return null; + } + // Determine the value of the discriminator property in the input data. + String discrValue = getDiscriminatorValue(node); + if (discrValue == null) { + return null; + } + Class cls = discriminatorMappings.get(discrValue); + // It may not be sufficient to return this cls directly because that target class + // may itself be a composed schema, possibly with its own discriminator. + visitedClasses.add(modelClass); + for (Class childClass : discriminatorMappings.values()) { + ClassDiscriminatorMapping childCdm = modelDiscriminators.get(childClass); + if (childCdm == null) { + continue; + } + if (!discriminatorName.equals(childCdm.discriminatorName)) { + discrValue = getDiscriminatorValue(node); + if (discrValue == null) { + continue; + } + } + if (childCdm != null) { + // Recursively traverse the discriminator mappings. + Class childDiscr = childCdm.getClassForElement(node, visitedClasses); + if (childDiscr != null) { + return childDiscr; + } + } + } + return cls; + } + } + + /** + * Returns true if inst is an instance of modelClass in the OpenAPI model hierarchy. + * + * The Java class hierarchy is not implemented the same way as the OpenAPI model hierarchy, + * so it's not possible to use the instanceof keyword. + * + * @param modelClass A OpenAPI model class. + * @param inst The instance object. + * @param visitedClasses The set of classes that have already been visited. + * + * @return true if inst is an instance of modelClass in the OpenAPI model hierarchy. + */ + public static boolean isInstanceOf(Class modelClass, Object inst, Set> visitedClasses) { + if (modelClass.isInstance(inst)) { + // This handles the 'allOf' use case with single parent inheritance. + return true; + } + if (visitedClasses.contains(modelClass)) { + // This is to prevent infinite recursion when the composed schemas have + // a circular dependency. + return false; + } + visitedClasses.add(modelClass); + + // Traverse the oneOf/anyOf composed schemas. + Map> descendants = modelDescendants.get(modelClass); + if (descendants != null) { + for (Class childType : descendants.values()) { + if (isInstanceOf(childType, inst, visitedClasses)) { + return true; + } + } + } + return false; + } + + /** + * A map of discriminators for all model classes. + */ + private static Map, ClassDiscriminatorMapping> modelDiscriminators = new HashMap<>(); + + /** + * A map of oneOf/anyOf descendants for each model class. + */ + private static Map, Map>> modelDescendants = new HashMap<>(); + + /** + * Register a model class discriminator. + * + * @param modelClass the model class + * @param discriminatorPropertyName the name of the discriminator property + * @param mappings a map with the discriminator mappings. + */ + public static void registerDiscriminator(Class modelClass, String discriminatorPropertyName, Map> mappings) { + ClassDiscriminatorMapping m = new ClassDiscriminatorMapping(modelClass, discriminatorPropertyName, mappings); + modelDiscriminators.put(modelClass, m); + } + + /** + * Register the oneOf/anyOf descendants of the modelClass. + * + * @param modelClass the model class + * @param descendants a map of oneOf/anyOf descendants. + */ + public static void registerDescendants(Class modelClass, Map> descendants) { + modelDescendants.put(modelClass, descendants); + } + + private static JSON json; + + static { + json = new JSON(); + } + + /** + * Get the default JSON instance. + * + * @return the default JSON instance + */ + public static JSON getDefault() { + return json; + } + + /** + * Set the default JSON instance. + * + * @param json JSON instance to be used + */ + public static void setDefault(JSON json) { + JSON.json = json; + } +} diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/Pair.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/Pair.java new file mode 100644 index 000000000000..2e29f6f31933 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/Pair.java @@ -0,0 +1,57 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Pair { + private String name = ""; + private String value = ""; + + public Pair (String name, String value) { + setName(name); + setValue(value); + } + + private void setName(String name) { + if (!isValidString(name)) { + return; + } + + this.name = name; + } + + private void setValue(String value) { + if (!isValidString(value)) { + return; + } + + this.value = value; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + private boolean isValidString(String arg) { + if (arg == null) { + return false; + } + + return true; + } +} diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/RFC3339DateFormat.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/RFC3339DateFormat.java new file mode 100644 index 000000000000..a1170edf7b43 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/RFC3339DateFormat.java @@ -0,0 +1,57 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package org.openapitools.client; + +import com.fasterxml.jackson.databind.util.StdDateFormat; + +import java.text.DateFormat; +import java.text.FieldPosition; +import java.text.ParsePosition; +import java.util.Date; +import java.text.DecimalFormat; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +public class RFC3339DateFormat extends DateFormat { + private static final long serialVersionUID = 1L; + private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC"); + + private final StdDateFormat fmt = new StdDateFormat() + .withTimeZone(TIMEZONE_Z) + .withColonInTimeZone(true); + + public RFC3339DateFormat() { + this.calendar = new GregorianCalendar(); + this.numberFormat = new DecimalFormat(); + } + + @Override + public Date parse(String source) { + return parse(source, new ParsePosition(0)); + } + + @Override + public Date parse(String source, ParsePosition pos) { + return fmt.parse(source, pos); + } + + @Override + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + return fmt.format(date, toAppendTo, fieldPosition); + } + + @Override + public Object clone() { + return super.clone(); + } +} \ No newline at end of file diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ServerConfiguration.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ServerConfiguration.java new file mode 100644 index 000000000000..ca5c1187edf2 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ServerConfiguration.java @@ -0,0 +1,58 @@ +package org.openapitools.client; + +import java.util.Map; + +/** + * Representing a Server configuration. + */ +public class ServerConfiguration { + public String URL; + public String description; + public Map variables; + + /** + * @param URL A URL to the target host. + * @param description A description of the host designated by the URL. + * @param variables A map between a variable name and its value. The value is used for substitution in the server's URL template. + */ + public ServerConfiguration(String URL, String description, Map variables) { + this.URL = URL; + this.description = description; + this.variables = variables; + } + + /** + * Format URL template using given variables. + * + * @param variables A map between a variable name and its value. + * @return Formatted URL. + */ + public String URL(Map variables) { + String url = this.URL; + + // go through variables and replace placeholders + for (Map.Entry variable: this.variables.entrySet()) { + String name = variable.getKey(); + ServerVariable serverVariable = variable.getValue(); + String value = serverVariable.defaultValue; + + if (variables != null && variables.containsKey(name)) { + value = variables.get(name); + if (serverVariable.enumValues.size() > 0 && !serverVariable.enumValues.contains(value)) { + throw new IllegalArgumentException("The variable " + name + " in the server URL has invalid value " + value + "."); + } + } + url = url.replaceAll("\\{" + name + "\\}", value); + } + return url; + } + + /** + * Format URL template using default server variables. + * + * @return Formatted URL. + */ + public String URL() { + return URL(null); + } +} diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ServerVariable.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ServerVariable.java new file mode 100644 index 000000000000..c2f13e216662 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/ServerVariable.java @@ -0,0 +1,23 @@ +package org.openapitools.client; + +import java.util.HashSet; + +/** + * Representing a Server Variable for server URL template substitution. + */ +public class ServerVariable { + public String description; + public String defaultValue; + public HashSet enumValues = null; + + /** + * @param description A description for the server variable. + * @param defaultValue The default value to use for substitution. + * @param enumValues An enumeration of string values to be used if the substitution options are from a limited set. + */ + public ServerVariable(String description, String defaultValue, HashSet enumValues) { + this.description = description; + this.defaultValue = defaultValue; + this.enumValues = enumValues; + } +} diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/api/DefaultApi.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/api/DefaultApi.java new file mode 100644 index 000000000000..685e46672008 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/api/DefaultApi.java @@ -0,0 +1,143 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package org.openapitools.client.api; + +import org.openapitools.client.ApiClient; +import org.openapitools.client.ApiException; +import org.openapitools.client.ApiResponse; +import org.openapitools.client.Pair; + +import org.openapitools.client.model.ModelWithNullableObjectProperty; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class DefaultApi { + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public DefaultApi() { + this(new ApiClient()); + } + + public DefaultApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + protected ApiException getApiException(String operationId, HttpResponse response) throws IOException { + String body = response.body() == null ? null : new String(response.body().readAllBytes()); + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * + * + * @return ModelWithNullableObjectProperty + * @throws ApiException if fails to make API call + */ + public ModelWithNullableObjectProperty operation() throws ApiException { + ApiResponse localVarResponse = operationWithHttpInfo(); + return localVarResponse.getData(); + } + + /** + * + * + * @return ApiResponse<ModelWithNullableObjectProperty> + * @throws ApiException if fails to make API call + */ + public ApiResponse operationWithHttpInfo() throws ApiException { + HttpRequest.Builder localVarRequestBuilder = operationRequestBuilder(); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("operation", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder operationRequestBuilder() throws ApiException { + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Accept", "application/json"); + + localVarRequestBuilder.method("GET", HttpRequest.BodyPublishers.noBody()); + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } +} diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/AbstractOpenApiSchema.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/AbstractOpenApiSchema.java new file mode 100644 index 000000000000..9e9efb5c6e4f --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/AbstractOpenApiSchema.java @@ -0,0 +1,148 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.model; + +import org.openapitools.client.ApiException; +import java.util.Objects; +import java.lang.reflect.Type; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Abstract class for oneOf,anyOf schemas defined in OpenAPI spec + */ +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public abstract class AbstractOpenApiSchema { + + // store the actual instance of the schema/object + private Object instance; + + // is nullable + private Boolean isNullable; + + // schema type (e.g. oneOf, anyOf) + private final String schemaType; + + public AbstractOpenApiSchema(String schemaType, Boolean isNullable) { + this.schemaType = schemaType; + this.isNullable = isNullable; + } + + /** + * Get the list of oneOf/anyOf composed schemas allowed to be stored in this object + * + * @return an instance of the actual schema/object + */ + public abstract Map> getSchemas(); + + /** + * Get the actual instance + * + * @return an instance of the actual schema/object + */ + @JsonValue + public Object getActualInstance() {return instance;} + + /** + * Set the actual instance + * + * @param instance the actual instance of the schema/object + */ + public void setActualInstance(Object instance) {this.instance = instance;} + + /** + * Get the instant recursively when the schemas defined in oneOf/anyof happen to be oneOf/anyOf schema as well + * + * @return an instance of the actual schema/object + */ + public Object getActualInstanceRecursively() { + return getActualInstanceRecursively(this); + } + + private Object getActualInstanceRecursively(AbstractOpenApiSchema object) { + if (object.getActualInstance() == null) { + return null; + } else if (object.getActualInstance() instanceof AbstractOpenApiSchema) { + return getActualInstanceRecursively((AbstractOpenApiSchema)object.getActualInstance()); + } else { + return object.getActualInstance(); + } + } + + /** + * Get the schema type (e.g. anyOf, oneOf) + * + * @return the schema type + */ + public String getSchemaType() { + return schemaType; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ").append(getClass()).append(" {\n"); + sb.append(" instance: ").append(toIndentedString(instance)).append("\n"); + sb.append(" isNullable: ").append(toIndentedString(isNullable)).append("\n"); + sb.append(" schemaType: ").append(toIndentedString(schemaType)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AbstractOpenApiSchema a = (AbstractOpenApiSchema) o; + return Objects.equals(this.instance, a.instance) && + Objects.equals(this.isNullable, a.isNullable) && + Objects.equals(this.schemaType, a.schemaType); + } + + @Override + public int hashCode() { + return Objects.hash(instance, isNullable, schemaType); + } + + /** + * Is nullable + * + * @return true if it's nullable + */ + public Boolean isNullable() { + if (Boolean.TRUE.equals(isNullable)) { + return Boolean.TRUE; + } else { + return Boolean.FALSE; + } + } + + + +} diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/ModelWithNullableObjectProperty.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/ModelWithNullableObjectProperty.java new file mode 100644 index 000000000000..562ad90ed9c9 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/ModelWithNullableObjectProperty.java @@ -0,0 +1,273 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.openapitools.client.model.ModelWithNullableObjectPropertyNonNullableProperty; +import org.openapitools.client.model.ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes; +import org.openapitools.client.model.PropertyType; +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.openapitools.jackson.nullable.JsonNullable; +import java.util.NoSuchElementException; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ModelWithNullableObjectProperty + */ +@JsonPropertyOrder({ + ModelWithNullableObjectProperty.JSON_PROPERTY_PROPERTY_NAME, + ModelWithNullableObjectProperty.JSON_PROPERTY_PROPERTY_NAME30, + ModelWithNullableObjectProperty.JSON_PROPERTY_PROPERTY_NAME31, + ModelWithNullableObjectProperty.JSON_PROPERTY_NON_NULLABLE_PROPERTY, + ModelWithNullableObjectProperty.JSON_PROPERTY_PROPERTY_WITH_NULL_AND_TWO_TYPES +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ModelWithNullableObjectProperty { + public static final String JSON_PROPERTY_PROPERTY_NAME = "propertyName"; + private PropertyType propertyName; + + public static final String JSON_PROPERTY_PROPERTY_NAME30 = "propertyName30"; + private JsonNullable propertyName30 = JsonNullable.undefined(); + + public static final String JSON_PROPERTY_PROPERTY_NAME31 = "propertyName31"; + private JsonNullable propertyName31 = JsonNullable.undefined(); + + public static final String JSON_PROPERTY_NON_NULLABLE_PROPERTY = "nonNullableProperty"; + private ModelWithNullableObjectPropertyNonNullableProperty nonNullableProperty; + + public static final String JSON_PROPERTY_PROPERTY_WITH_NULL_AND_TWO_TYPES = "propertyWithNullAndTwoTypes"; + private ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes propertyWithNullAndTwoTypes; + + public ModelWithNullableObjectProperty() { + } + + public ModelWithNullableObjectProperty propertyName(PropertyType propertyName) { + this.propertyName = propertyName; + return this; + } + + /** + * Get propertyName + * @return propertyName + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_PROPERTY_NAME) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public PropertyType getPropertyName() { + return propertyName; + } + + + @JsonProperty(JSON_PROPERTY_PROPERTY_NAME) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPropertyName(PropertyType propertyName) { + this.propertyName = propertyName; + } + + + public ModelWithNullableObjectProperty propertyName30(PropertyType propertyName30) { + this.propertyName30 = JsonNullable.of(propertyName30); + return this; + } + + /** + * Get propertyName30 + * @return propertyName30 + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonIgnore + + public PropertyType getPropertyName30() { + return propertyName30.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_PROPERTY_NAME30) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public JsonNullable getPropertyName30_JsonNullable() { + return propertyName30; + } + + @JsonProperty(JSON_PROPERTY_PROPERTY_NAME30) + public void setPropertyName30_JsonNullable(JsonNullable propertyName30) { + this.propertyName30 = propertyName30; + } + + public void setPropertyName30(PropertyType propertyName30) { + this.propertyName30 = JsonNullable.of(propertyName30); + } + + + public ModelWithNullableObjectProperty propertyName31(PropertyType propertyName31) { + this.propertyName31 = JsonNullable.of(propertyName31); + return this; + } + + /** + * Get propertyName31 + * @return propertyName31 + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonIgnore + + public PropertyType getPropertyName31() { + return propertyName31.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_PROPERTY_NAME31) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public JsonNullable getPropertyName31_JsonNullable() { + return propertyName31; + } + + @JsonProperty(JSON_PROPERTY_PROPERTY_NAME31) + public void setPropertyName31_JsonNullable(JsonNullable propertyName31) { + this.propertyName31 = propertyName31; + } + + public void setPropertyName31(PropertyType propertyName31) { + this.propertyName31 = JsonNullable.of(propertyName31); + } + + + public ModelWithNullableObjectProperty nonNullableProperty(ModelWithNullableObjectPropertyNonNullableProperty nonNullableProperty) { + this.nonNullableProperty = nonNullableProperty; + return this; + } + + /** + * Get nonNullableProperty + * @return nonNullableProperty + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_NON_NULLABLE_PROPERTY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public ModelWithNullableObjectPropertyNonNullableProperty getNonNullableProperty() { + return nonNullableProperty; + } + + + @JsonProperty(JSON_PROPERTY_NON_NULLABLE_PROPERTY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setNonNullableProperty(ModelWithNullableObjectPropertyNonNullableProperty nonNullableProperty) { + this.nonNullableProperty = nonNullableProperty; + } + + + public ModelWithNullableObjectProperty propertyWithNullAndTwoTypes(ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes propertyWithNullAndTwoTypes) { + this.propertyWithNullAndTwoTypes = propertyWithNullAndTwoTypes; + return this; + } + + /** + * Get propertyWithNullAndTwoTypes + * @return propertyWithNullAndTwoTypes + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_PROPERTY_WITH_NULL_AND_TWO_TYPES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes getPropertyWithNullAndTwoTypes() { + return propertyWithNullAndTwoTypes; + } + + + @JsonProperty(JSON_PROPERTY_PROPERTY_WITH_NULL_AND_TWO_TYPES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPropertyWithNullAndTwoTypes(ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes propertyWithNullAndTwoTypes) { + this.propertyWithNullAndTwoTypes = propertyWithNullAndTwoTypes; + } + + + /** + * Return true if this ModelWithNullableObjectProperty object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ModelWithNullableObjectProperty modelWithNullableObjectProperty = (ModelWithNullableObjectProperty) o; + return Objects.equals(this.propertyName, modelWithNullableObjectProperty.propertyName) && + equalsNullable(this.propertyName30, modelWithNullableObjectProperty.propertyName30) && + equalsNullable(this.propertyName31, modelWithNullableObjectProperty.propertyName31) && + Objects.equals(this.nonNullableProperty, modelWithNullableObjectProperty.nonNullableProperty) && + Objects.equals(this.propertyWithNullAndTwoTypes, modelWithNullableObjectProperty.propertyWithNullAndTwoTypes); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(propertyName, hashCodeNullable(propertyName30), hashCodeNullable(propertyName31), nonNullableProperty, propertyWithNullAndTwoTypes); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ModelWithNullableObjectProperty {\n"); + sb.append(" propertyName: ").append(toIndentedString(propertyName)).append("\n"); + sb.append(" propertyName30: ").append(toIndentedString(propertyName30)).append("\n"); + sb.append(" propertyName31: ").append(toIndentedString(propertyName31)).append("\n"); + sb.append(" nonNullableProperty: ").append(toIndentedString(nonNullableProperty)).append("\n"); + sb.append(" propertyWithNullAndTwoTypes: ").append(toIndentedString(propertyWithNullAndTwoTypes)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/ModelWithNullableObjectPropertyNonNullableProperty.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/ModelWithNullableObjectPropertyNonNullableProperty.java new file mode 100644 index 000000000000..86f8758a9c02 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/ModelWithNullableObjectPropertyNonNullableProperty.java @@ -0,0 +1,237 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import com.fasterxml.jackson.core.type.TypeReference; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import org.openapitools.client.JSON; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +@JsonDeserialize(using = ModelWithNullableObjectPropertyNonNullableProperty.ModelWithNullableObjectPropertyNonNullablePropertyDeserializer.class) +@JsonSerialize(using = ModelWithNullableObjectPropertyNonNullableProperty.ModelWithNullableObjectPropertyNonNullablePropertySerializer.class) +public class ModelWithNullableObjectPropertyNonNullableProperty extends AbstractOpenApiSchema { + private static final Logger log = Logger.getLogger(ModelWithNullableObjectPropertyNonNullableProperty.class.getName()); + + public static class ModelWithNullableObjectPropertyNonNullablePropertySerializer extends StdSerializer { + public ModelWithNullableObjectPropertyNonNullablePropertySerializer(Class t) { + super(t); + } + + public ModelWithNullableObjectPropertyNonNullablePropertySerializer() { + this(null); + } + + @Override + public void serialize(ModelWithNullableObjectPropertyNonNullableProperty value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeObject(value.getActualInstance()); + } + } + + public static class ModelWithNullableObjectPropertyNonNullablePropertyDeserializer extends StdDeserializer { + public ModelWithNullableObjectPropertyNonNullablePropertyDeserializer() { + this(ModelWithNullableObjectPropertyNonNullableProperty.class); + } + + public ModelWithNullableObjectPropertyNonNullablePropertyDeserializer(Class vc) { + super(vc); + } + + @Override + public ModelWithNullableObjectPropertyNonNullableProperty deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + JsonNode tree = jp.readValueAsTree(); + Object deserialized = null; + boolean typeCoercion = ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS); + int match = 0; + JsonToken token = tree.traverse(jp.getCodec()).nextToken(); + // deserialize BigDecimal + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (BigDecimal.class.equals(Integer.class) || BigDecimal.class.equals(Long.class) || BigDecimal.class.equals(Float.class) || BigDecimal.class.equals(Double.class) || BigDecimal.class.equals(Boolean.class) || BigDecimal.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= ((BigDecimal.class.equals(Integer.class) || BigDecimal.class.equals(Long.class)) && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= ((BigDecimal.class.equals(Float.class) || BigDecimal.class.equals(Double.class)) && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= (BigDecimal.class.equals(Boolean.class) && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= (BigDecimal.class.equals(String.class) && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(BigDecimal.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'BigDecimal'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'BigDecimal'", e); + } + + // deserialize String + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (String.class.equals(Integer.class) || String.class.equals(Long.class) || String.class.equals(Float.class) || String.class.equals(Double.class) || String.class.equals(Boolean.class) || String.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= ((String.class.equals(Integer.class) || String.class.equals(Long.class)) && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= ((String.class.equals(Float.class) || String.class.equals(Double.class)) && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= (String.class.equals(Boolean.class) && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= (String.class.equals(String.class) && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(String.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'String'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'String'", e); + } + + if (match == 1) { + ModelWithNullableObjectPropertyNonNullableProperty ret = new ModelWithNullableObjectPropertyNonNullableProperty(); + ret.setActualInstance(deserialized); + return ret; + } + throw new IOException(String.format("Failed deserialization for ModelWithNullableObjectPropertyNonNullableProperty: %d classes match result, expected 1", match)); + } + + /** + * Handle deserialization of the 'null' value. + */ + @Override + public ModelWithNullableObjectPropertyNonNullableProperty getNullValue(DeserializationContext ctxt) throws JsonMappingException { + throw new JsonMappingException(ctxt.getParser(), "ModelWithNullableObjectPropertyNonNullableProperty cannot be null"); + } + } + + // store a list of schema names defined in oneOf + public static final Map> schemas = new HashMap<>(); + + public ModelWithNullableObjectPropertyNonNullableProperty() { + super("oneOf", Boolean.FALSE); + } + + public ModelWithNullableObjectPropertyNonNullableProperty(BigDecimal o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + public ModelWithNullableObjectPropertyNonNullableProperty(String o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + static { + schemas.put("BigDecimal", BigDecimal.class); + schemas.put("String", String.class); + JSON.registerDescendants(ModelWithNullableObjectPropertyNonNullableProperty.class, Collections.unmodifiableMap(schemas)); + } + + @Override + public Map> getSchemas() { + return ModelWithNullableObjectPropertyNonNullableProperty.schemas; + } + + /** + * Set the instance that matches the oneOf child schema, check + * the instance parameter is valid against the oneOf child schemas: + * BigDecimal, String + * + * It could be an instance of the 'oneOf' schemas. + * The oneOf child schemas may themselves be a composed schema (allOf, anyOf, oneOf). + */ + @Override + public void setActualInstance(Object instance) { + if (JSON.isInstanceOf(BigDecimal.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + if (JSON.isInstanceOf(String.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + throw new RuntimeException("Invalid instance type. Must be BigDecimal, String"); + } + + /** + * Get the actual instance, which can be the following: + * BigDecimal, String + * + * @return The actual instance (BigDecimal, String) + */ + @Override + public Object getActualInstance() { + return super.getActualInstance(); + } + + /** + * Get the actual instance of `BigDecimal`. If the actual instance is not `BigDecimal`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `BigDecimal` + * @throws ClassCastException if the instance is not `BigDecimal` + */ + public BigDecimal getBigDecimal() throws ClassCastException { + return (BigDecimal)super.getActualInstance(); + } + + /** + * Get the actual instance of `String`. If the actual instance is not `String`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `String` + * @throws ClassCastException if the instance is not `String` + */ + public String getString() throws ClassCastException { + return (String)super.getActualInstance(); + } + +} + diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.java new file mode 100644 index 000000000000..6366fe07c273 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.java @@ -0,0 +1,253 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.openapitools.client.model.OtherPropertyType; +import org.openapitools.client.model.PropertyType; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import com.fasterxml.jackson.core.type.TypeReference; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import org.openapitools.client.JSON; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +@JsonDeserialize(using = ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesDeserializer.class) +@JsonSerialize(using = ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesSerializer.class) +public class ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes extends AbstractOpenApiSchema { + private static final Logger log = Logger.getLogger(ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.class.getName()); + + public static class ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesSerializer extends StdSerializer { + public ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesSerializer(Class t) { + super(t); + } + + public ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesSerializer() { + this(null); + } + + @Override + public void serialize(ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeObject(value.getActualInstance()); + } + } + + public static class ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesDeserializer extends StdDeserializer { + public ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesDeserializer() { + this(ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.class); + } + + public ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesDeserializer(Class vc) { + super(vc); + } + + @Override + public ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + JsonNode tree = jp.readValueAsTree(); + Object deserialized = null; + boolean typeCoercion = ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS); + int match = 0; + JsonToken token = tree.traverse(jp.getCodec()).nextToken(); + // deserialize OtherPropertyType + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (OtherPropertyType.class.equals(Integer.class) || OtherPropertyType.class.equals(Long.class) || OtherPropertyType.class.equals(Float.class) || OtherPropertyType.class.equals(Double.class) || OtherPropertyType.class.equals(Boolean.class) || OtherPropertyType.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= ((OtherPropertyType.class.equals(Integer.class) || OtherPropertyType.class.equals(Long.class)) && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= ((OtherPropertyType.class.equals(Float.class) || OtherPropertyType.class.equals(Double.class)) && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= (OtherPropertyType.class.equals(Boolean.class) && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= (OtherPropertyType.class.equals(String.class) && token == JsonToken.VALUE_STRING); + attemptParsing |= (token == JsonToken.VALUE_NULL); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(OtherPropertyType.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'OtherPropertyType'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'OtherPropertyType'", e); + } + + // deserialize PropertyType + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (PropertyType.class.equals(Integer.class) || PropertyType.class.equals(Long.class) || PropertyType.class.equals(Float.class) || PropertyType.class.equals(Double.class) || PropertyType.class.equals(Boolean.class) || PropertyType.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= ((PropertyType.class.equals(Integer.class) || PropertyType.class.equals(Long.class)) && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= ((PropertyType.class.equals(Float.class) || PropertyType.class.equals(Double.class)) && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= (PropertyType.class.equals(Boolean.class) && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= (PropertyType.class.equals(String.class) && token == JsonToken.VALUE_STRING); + attemptParsing |= (token == JsonToken.VALUE_NULL); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(PropertyType.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'PropertyType'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'PropertyType'", e); + } + + if (match == 1) { + ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes ret = new ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes(); + ret.setActualInstance(deserialized); + return ret; + } + throw new IOException(String.format("Failed deserialization for ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes: %d classes match result, expected 1", match)); + } + + /** + * Handle deserialization of the 'null' value. + */ + @Override + public ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes getNullValue(DeserializationContext ctxt) throws JsonMappingException { + return null; + } + } + + // store a list of schema names defined in oneOf + public static final Map> schemas = new HashMap<>(); + + public ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes() { + super("oneOf", Boolean.TRUE); + } + + public ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes(OtherPropertyType o) { + super("oneOf", Boolean.TRUE); + setActualInstance(o); + } + + public ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes(PropertyType o) { + super("oneOf", Boolean.TRUE); + setActualInstance(o); + } + + static { + schemas.put("OtherPropertyType", OtherPropertyType.class); + schemas.put("PropertyType", PropertyType.class); + JSON.registerDescendants(ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.class, Collections.unmodifiableMap(schemas)); + } + + @Override + public Map> getSchemas() { + return ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.schemas; + } + + /** + * Set the instance that matches the oneOf child schema, check + * the instance parameter is valid against the oneOf child schemas: + * OtherPropertyType, PropertyType + * + * It could be an instance of the 'oneOf' schemas. + * The oneOf child schemas may themselves be a composed schema (allOf, anyOf, oneOf). + */ + @Override + public void setActualInstance(Object instance) { + if (instance == null) { + super.setActualInstance(instance); + return; + } + + if (JSON.isInstanceOf(OtherPropertyType.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + if (JSON.isInstanceOf(PropertyType.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + throw new RuntimeException("Invalid instance type. Must be OtherPropertyType, PropertyType"); + } + + /** + * Get the actual instance, which can be the following: + * OtherPropertyType, PropertyType + * + * @return The actual instance (OtherPropertyType, PropertyType) + */ + @Override + public Object getActualInstance() { + return super.getActualInstance(); + } + + /** + * Get the actual instance of `OtherPropertyType`. If the actual instance is not `OtherPropertyType`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `OtherPropertyType` + * @throws ClassCastException if the instance is not `OtherPropertyType` + */ + public OtherPropertyType getOtherPropertyType() throws ClassCastException { + return (OtherPropertyType)super.getActualInstance(); + } + + /** + * Get the actual instance of `PropertyType`. If the actual instance is not `PropertyType`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `PropertyType` + * @throws ClassCastException if the instance is not `PropertyType` + */ + public PropertyType getPropertyType() throws ClassCastException { + return (PropertyType)super.getActualInstance(); + } + +} + diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/OtherPropertyType.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/OtherPropertyType.java new file mode 100644 index 000000000000..6c5cf2773d5e --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/OtherPropertyType.java @@ -0,0 +1,111 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * OtherPropertyType + */ +@JsonPropertyOrder({ + OtherPropertyType.JSON_PROPERTY_BAR +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class OtherPropertyType { + public static final String JSON_PROPERTY_BAR = "bar"; + private String bar; + + public OtherPropertyType() { + } + + public OtherPropertyType bar(String bar) { + this.bar = bar; + return this; + } + + /** + * Get bar + * @return bar + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_BAR) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getBar() { + return bar; + } + + + @JsonProperty(JSON_PROPERTY_BAR) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setBar(String bar) { + this.bar = bar; + } + + + /** + * Return true if this OtherPropertyType object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + OtherPropertyType otherPropertyType = (OtherPropertyType) o; + return Objects.equals(this.bar, otherPropertyType.bar); + } + + @Override + public int hashCode() { + return Objects.hash(bar); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class OtherPropertyType {\n"); + sb.append(" bar: ").append(toIndentedString(bar)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/PropertyType.java b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/PropertyType.java new file mode 100644 index 000000000000..d0606419e194 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/main/java/org/openapitools/client/model/PropertyType.java @@ -0,0 +1,111 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.model; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * PropertyType + */ +@JsonPropertyOrder({ + PropertyType.JSON_PROPERTY_FOO +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class PropertyType { + public static final String JSON_PROPERTY_FOO = "foo"; + private String foo; + + public PropertyType() { + } + + public PropertyType foo(String foo) { + this.foo = foo; + return this; + } + + /** + * Get foo + * @return foo + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_FOO) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getFoo() { + return foo; + } + + + @JsonProperty(JSON_PROPERTY_FOO) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setFoo(String foo) { + this.foo = foo; + } + + + /** + * Return true if this PropertyType object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PropertyType propertyType = (PropertyType) o; + return Objects.equals(this.foo, propertyType.foo); + } + + @Override + public int hashCode() { + return Objects.hash(foo); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class PropertyType {\n"); + sb.append(" foo: ").append(toIndentedString(foo)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/api/DefaultApiTest.java b/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/api/DefaultApiTest.java new file mode 100644 index 000000000000..6bcd2ea4b78e --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/api/DefaultApiTest.java @@ -0,0 +1,53 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.api; + +import org.openapitools.client.ApiException; +import org.openapitools.client.model.ModelWithNullableObjectProperty; +import org.junit.Test; +import org.junit.Ignore; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +/** + * API tests for DefaultApi + */ +@Ignore +public class DefaultApiTest { + + private final DefaultApi api = new DefaultApi(); + + + /** + * + * + * + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void operationTest() throws ApiException { + ModelWithNullableObjectProperty response = + api.operation(); + + // TODO: test validations + } + +} diff --git a/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/ModelWithNullableObjectPropertyNonNullablePropertyTest.java b/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/ModelWithNullableObjectPropertyNonNullablePropertyTest.java new file mode 100644 index 000000000000..42b0b34326bd --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/ModelWithNullableObjectPropertyNonNullablePropertyTest.java @@ -0,0 +1,35 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.model; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for ModelWithNullableObjectPropertyNonNullableProperty + */ +public class ModelWithNullableObjectPropertyNonNullablePropertyTest { + private final ModelWithNullableObjectPropertyNonNullableProperty model = new ModelWithNullableObjectPropertyNonNullableProperty(); + + /** + * Model tests for ModelWithNullableObjectPropertyNonNullableProperty + */ + @Test + public void testModelWithNullableObjectPropertyNonNullableProperty() { + // TODO: test ModelWithNullableObjectPropertyNonNullableProperty + } + +} diff --git a/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesTest.java b/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesTest.java new file mode 100644 index 000000000000..a55d2a184bfd --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesTest.java @@ -0,0 +1,60 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.openapitools.client.model.OtherPropertyType; +import org.openapitools.client.model.PropertyType; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes + */ +public class ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesTest { + private final ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes model = new ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes(); + + /** + * Model tests for ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes + */ + @Test + public void testModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes() { + // TODO: test ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes + } + + /** + * Test the property 'foo' + */ + @Test + public void fooTest() { + // TODO: test foo + } + + /** + * Test the property 'bar' + */ + @Test + public void barTest() { + // TODO: test bar + } + +} diff --git a/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/ModelWithNullableObjectPropertyTest.java b/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/ModelWithNullableObjectPropertyTest.java new file mode 100644 index 000000000000..2a9d9601478f --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/ModelWithNullableObjectPropertyTest.java @@ -0,0 +1,90 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.openapitools.client.model.ModelNull; +import org.openapitools.client.model.ModelWithNullableObjectPropertyNonNullableProperty; +import org.openapitools.client.model.ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes; +import org.openapitools.client.model.PropertyType; +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.openapitools.jackson.nullable.JsonNullable; +import java.util.NoSuchElementException; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for ModelWithNullableObjectProperty + */ +public class ModelWithNullableObjectPropertyTest { + private final ModelWithNullableObjectProperty model = new ModelWithNullableObjectProperty(); + + /** + * Model tests for ModelWithNullableObjectProperty + */ + @Test + public void testModelWithNullableObjectProperty() { + // TODO: test ModelWithNullableObjectProperty + } + + /** + * Test the property 'propertyName' + */ + @Test + public void propertyNameTest() { + // TODO: test propertyName + } + + /** + * Test the property 'propertyName30' + */ + @Test + public void propertyName30Test() { + // TODO: test propertyName30 + } + + /** + * Test the property 'propertyName31' + */ + @Test + public void propertyName31Test() { + // TODO: test propertyName31 + } + + /** + * Test the property 'nonNullableProperty' + */ + @Test + public void nonNullablePropertyTest() { + // TODO: test nonNullableProperty + } + + /** + * Test the property 'propertyWithNullAndTwoTypes' + */ + @Test + public void propertyWithNullAndTwoTypesTest() { + // TODO: test propertyWithNullAndTwoTypes + } + +} diff --git a/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/OtherPropertyTypeTest.java b/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/OtherPropertyTypeTest.java new file mode 100644 index 000000000000..9b5320e2ada1 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/OtherPropertyTypeTest.java @@ -0,0 +1,50 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for OtherPropertyType + */ +public class OtherPropertyTypeTest { + private final OtherPropertyType model = new OtherPropertyType(); + + /** + * Model tests for OtherPropertyType + */ + @Test + public void testOtherPropertyType() { + // TODO: test OtherPropertyType + } + + /** + * Test the property 'bar' + */ + @Test + public void barTest() { + // TODO: test bar + } + +} diff --git a/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/PropertyTypeTest.java b/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/PropertyTypeTest.java new file mode 100644 index 000000000000..ebc88d77df20 --- /dev/null +++ b/samples/client/petstore/java/nullable-object-property/src/test/java/org/openapitools/client/model/PropertyTypeTest.java @@ -0,0 +1,50 @@ +/* + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for PropertyType + */ +public class PropertyTypeTest { + private final PropertyType model = new PropertyType(); + + /** + * Model tests for PropertyType + */ + @Test + public void testPropertyType() { + // TODO: test PropertyType + } + + /** + * Test the property 'foo' + */ + @Test + public void fooTest() { + // TODO: test foo + } + +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/.openapi-generator-ignore b/samples/client/petstore/kotlin-nullable-object-propery/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore/kotlin-nullable-object-propery/.openapi-generator/FILES b/samples/client/petstore/kotlin-nullable-object-propery/.openapi-generator/FILES new file mode 100644 index 000000000000..af1de9e390fd --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/.openapi-generator/FILES @@ -0,0 +1,36 @@ +README.md +build.gradle +docs/DefaultApi.md +docs/ModelWithNullableObjectProperty.md +docs/ModelWithNullableObjectPropertyNonNullableProperty.md +docs/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md +docs/OtherPropertyType.md +docs/PropertyType.md +gradle/wrapper/gradle-wrapper.jar +gradle/wrapper/gradle-wrapper.properties +gradlew +gradlew.bat +settings.gradle +src/main/kotlin/org/openapitools/client/apis/DefaultApi.kt +src/main/kotlin/org/openapitools/client/infrastructure/ApiAbstractions.kt +src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt +src/main/kotlin/org/openapitools/client/infrastructure/ApiResponse.kt +src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt +src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt +src/main/kotlin/org/openapitools/client/infrastructure/ByteArrayAdapter.kt +src/main/kotlin/org/openapitools/client/infrastructure/Errors.kt +src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt +src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt +src/main/kotlin/org/openapitools/client/infrastructure/OffsetDateTimeAdapter.kt +src/main/kotlin/org/openapitools/client/infrastructure/PartConfig.kt +src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt +src/main/kotlin/org/openapitools/client/infrastructure/RequestMethod.kt +src/main/kotlin/org/openapitools/client/infrastructure/ResponseExtensions.kt +src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt +src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt +src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt +src/main/kotlin/org/openapitools/client/models/ModelWithNullableObjectProperty.kt +src/main/kotlin/org/openapitools/client/models/ModelWithNullableObjectPropertyNonNullableProperty.kt +src/main/kotlin/org/openapitools/client/models/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.kt +src/main/kotlin/org/openapitools/client/models/OtherPropertyType.kt +src/main/kotlin/org/openapitools/client/models/PropertyType.kt diff --git a/samples/client/petstore/kotlin-nullable-object-propery/.openapi-generator/VERSION b/samples/client/petstore/kotlin-nullable-object-propery/.openapi-generator/VERSION new file mode 100644 index 000000000000..66672d4e9d31 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/.openapi-generator/VERSION @@ -0,0 +1 @@ +6.1.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/kotlin-nullable-object-propery/README.md b/samples/client/petstore/kotlin-nullable-object-propery/README.md new file mode 100644 index 000000000000..775ce53e6614 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/README.md @@ -0,0 +1,54 @@ +# org.openapitools.client - Kotlin client library for Title + +## Requires + +* Kotlin 1.4.30 +* Gradle 6.8.3 + +## Build + +First, create the gradle wrapper script: + +``` +gradle wrapper +``` + +Then, run: + +``` +./gradlew check assemble +``` + +This runs all tests and packages the library. + +## Features/Implementation Notes + +* Supports JSON inputs/outputs, File inputs, and Form inputs. +* Supports collection formats for query parameters: csv, tsv, ssv, pipes. +* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions. +* Implementation of ApiClient is intended to reduce method counts, specifically to benefit Android targets. + + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*DefaultApi* | [**operation**](docs/DefaultApi.md#operation) | **GET** / | + + + +## Documentation for Models + + - [org.openapitools.client.models.ModelWithNullableObjectProperty](docs/ModelWithNullableObjectProperty.md) + - [org.openapitools.client.models.ModelWithNullableObjectPropertyNonNullableProperty](docs/ModelWithNullableObjectPropertyNonNullableProperty.md) + - [org.openapitools.client.models.ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes](docs/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md) + - [org.openapitools.client.models.OtherPropertyType](docs/OtherPropertyType.md) + - [org.openapitools.client.models.PropertyType](docs/PropertyType.md) + + + +## Documentation for Authorization + +All endpoints do not require authorization. diff --git a/samples/client/petstore/kotlin-nullable-object-propery/build.gradle b/samples/client/petstore/kotlin-nullable-object-propery/build.gradle new file mode 100644 index 000000000000..3de8b45b135e --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/build.gradle @@ -0,0 +1,37 @@ +group 'org.openapitools' +version '1.0.0' + +wrapper { + gradleVersion = '6.8.3' + distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip" +} + +buildscript { + ext.kotlin_version = '1.5.10' + + repositories { + maven { url "https://repo1.maven.org/maven2" } + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'kotlin' + +repositories { + maven { url "https://repo1.maven.org/maven2" } +} + +test { + useJUnitPlatform() +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" + implementation "com.squareup.moshi:moshi-kotlin:1.12.0" + implementation "com.squareup.moshi:moshi-adapters:1.12.0" + implementation "com.squareup.okhttp3:okhttp:4.9.1" + testImplementation "io.kotlintest:kotlintest-runner-junit5:3.4.2" +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/docs/DefaultApi.md b/samples/client/petstore/kotlin-nullable-object-propery/docs/DefaultApi.md new file mode 100644 index 000000000000..f5ae1c35f79d --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/docs/DefaultApi.md @@ -0,0 +1,50 @@ +# DefaultApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**operation**](DefaultApi.md#operation) | **GET** / | + + + +# **operation** +> ModelWithNullableObjectProperty operation() + + + +### Example +```kotlin +// Import classes: +//import org.openapitools.client.infrastructure.* +//import org.openapitools.client.models.* + +val apiInstance = DefaultApi() +try { + val result : ModelWithNullableObjectProperty? = apiInstance.operation() + println(result) +} catch (e: ClientException) { + println("4xx response calling DefaultApi#operation") + e.printStackTrace() +} catch (e: ServerException) { + println("5xx response calling DefaultApi#operation") + e.printStackTrace() +} +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**ModelWithNullableObjectProperty**](ModelWithNullableObjectProperty.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + diff --git a/samples/client/petstore/kotlin-nullable-object-propery/docs/ModelWithNullableObjectProperty.md b/samples/client/petstore/kotlin-nullable-object-propery/docs/ModelWithNullableObjectProperty.md new file mode 100644 index 000000000000..36fdda3237bd --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/docs/ModelWithNullableObjectProperty.md @@ -0,0 +1,14 @@ + +# ModelWithNullableObjectProperty + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**propertyName** | [**PropertyType**](PropertyType.md) | | [optional] +**propertyName30** | [**PropertyType**](PropertyType.md) | | [optional] +**propertyName31** | [**PropertyType**](PropertyType.md) | | [optional] +**nonNullableProperty** | [**ModelWithNullableObjectPropertyNonNullableProperty**](ModelWithNullableObjectPropertyNonNullableProperty.md) | | [optional] +**propertyWithNullAndTwoTypes** | [**ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes**](ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md) | | [optional] + + + diff --git a/samples/client/petstore/kotlin-nullable-object-propery/docs/ModelWithNullableObjectPropertyNonNullableProperty.md b/samples/client/petstore/kotlin-nullable-object-propery/docs/ModelWithNullableObjectPropertyNonNullableProperty.md new file mode 100644 index 000000000000..aeed01ed68e4 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/docs/ModelWithNullableObjectPropertyNonNullableProperty.md @@ -0,0 +1,9 @@ + +# ModelWithNullableObjectPropertyNonNullableProperty + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + + + diff --git a/samples/client/petstore/kotlin-nullable-object-propery/docs/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md b/samples/client/petstore/kotlin-nullable-object-propery/docs/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md new file mode 100644 index 000000000000..a4bbfe2c6986 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/docs/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md @@ -0,0 +1,11 @@ + +# ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**foo** | **kotlin.String** | | [optional] +**bar** | **kotlin.String** | | [optional] + + + diff --git a/samples/client/petstore/kotlin-nullable-object-propery/docs/OtherPropertyType.md b/samples/client/petstore/kotlin-nullable-object-propery/docs/OtherPropertyType.md new file mode 100644 index 000000000000..6a0934bb8302 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/docs/OtherPropertyType.md @@ -0,0 +1,10 @@ + +# OtherPropertyType + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**bar** | **kotlin.String** | | [optional] + + + diff --git a/samples/client/petstore/kotlin-nullable-object-propery/docs/PropertyType.md b/samples/client/petstore/kotlin-nullable-object-propery/docs/PropertyType.md new file mode 100644 index 000000000000..2bcf9381036f --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/docs/PropertyType.md @@ -0,0 +1,10 @@ + +# PropertyType + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**foo** | **kotlin.String** | | [optional] + + + diff --git a/samples/client/petstore/kotlin-nullable-object-propery/gradle/wrapper/gradle-wrapper.jar b/samples/client/petstore/kotlin-nullable-object-propery/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000000..e708b1c023ec Binary files /dev/null and b/samples/client/petstore/kotlin-nullable-object-propery/gradle/wrapper/gradle-wrapper.jar differ diff --git a/samples/client/petstore/kotlin-nullable-object-propery/gradle/wrapper/gradle-wrapper.properties b/samples/client/petstore/kotlin-nullable-object-propery/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..8cf6eb5ad222 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/samples/client/petstore/kotlin-nullable-object-propery/gradlew b/samples/client/petstore/kotlin-nullable-object-propery/gradlew new file mode 100644 index 000000000000..4f906e0c811f --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/samples/client/petstore/kotlin-nullable-object-propery/gradlew.bat b/samples/client/petstore/kotlin-nullable-object-propery/gradlew.bat new file mode 100644 index 000000000000..107acd32c4e6 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/samples/client/petstore/kotlin-nullable-object-propery/settings.gradle b/samples/client/petstore/kotlin-nullable-object-propery/settings.gradle new file mode 100644 index 000000000000..bbaa51a0e9ad --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/settings.gradle @@ -0,0 +1,2 @@ + +rootProject.name = 'nullable-object-property' \ No newline at end of file diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/apis/DefaultApi.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/apis/DefaultApi.kt new file mode 100644 index 000000000000..fedc8575066c --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/apis/DefaultApi.kt @@ -0,0 +1,119 @@ +/** + * Title + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.apis + +import java.io.IOException +import okhttp3.OkHttpClient + +import org.openapitools.client.models.ModelWithNullableObjectProperty + +import com.squareup.moshi.Json + +import org.openapitools.client.infrastructure.ApiClient +import org.openapitools.client.infrastructure.ApiResponse +import org.openapitools.client.infrastructure.ClientException +import org.openapitools.client.infrastructure.ClientError +import org.openapitools.client.infrastructure.ServerException +import org.openapitools.client.infrastructure.ServerError +import org.openapitools.client.infrastructure.MultiValueMap +import org.openapitools.client.infrastructure.PartConfig +import org.openapitools.client.infrastructure.RequestConfig +import org.openapitools.client.infrastructure.RequestMethod +import org.openapitools.client.infrastructure.ResponseType +import org.openapitools.client.infrastructure.Success +import org.openapitools.client.infrastructure.toMultiValue + +class DefaultApi(basePath: kotlin.String = defaultBasePath, client: OkHttpClient = ApiClient.defaultClient) : ApiClient(basePath, client) { + companion object { + @JvmStatic + val defaultBasePath: String by lazy { + System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost") + } + } + + /** + * + * + * @return ModelWithNullableObjectProperty or null + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + * @throws UnsupportedOperationException If the API returns an informational or redirection response + * @throws ClientException If the API returns a client error response + * @throws ServerException If the API returns a server error response + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class, UnsupportedOperationException::class, ClientException::class, ServerException::class) + fun operation() : ModelWithNullableObjectProperty? { + val localVarResponse = operationWithHttpInfo() + + return when (localVarResponse.responseType) { + ResponseType.Success -> (localVarResponse as Success<*>).data as ModelWithNullableObjectProperty? + ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.") + ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.") + ResponseType.ClientError -> { + val localVarError = localVarResponse as ClientError<*> + throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse) + } + ResponseType.ServerError -> { + val localVarError = localVarResponse as ServerError<*> + throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse) + } + } + } + + /** + * + * + * @return ApiResponse + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class) + fun operationWithHttpInfo() : ApiResponse { + val localVariableConfig = operationRequestConfig() + + return request( + localVariableConfig + ) + } + + /** + * To obtain the request config of the operation operation + * + * @return RequestConfig + */ + fun operationRequestConfig() : RequestConfig { + val localVariableBody = null + val localVariableQuery: MultiValueMap = mutableMapOf() + val localVariableHeaders: MutableMap = mutableMapOf() + localVariableHeaders["Accept"] = "application/json" + + return RequestConfig( + method = RequestMethod.GET, + path = "/", + query = localVariableQuery, + headers = localVariableHeaders, + body = localVariableBody + ) + } + +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ApiAbstractions.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ApiAbstractions.kt new file mode 100644 index 000000000000..ef7a8f1e1a62 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ApiAbstractions.kt @@ -0,0 +1,23 @@ +package org.openapitools.client.infrastructure + +typealias MultiValueMap = MutableMap> + +fun collectionDelimiter(collectionFormat: String) = when(collectionFormat) { + "csv" -> "," + "tsv" -> "\t" + "pipe" -> "|" + "space" -> " " + else -> "" +} + +val defaultMultiValueConverter: (item: Any?) -> String = { item -> "$item" } + +fun toMultiValue(items: Array, collectionFormat: String, map: (item: T) -> String = defaultMultiValueConverter) + = toMultiValue(items.asIterable(), collectionFormat, map) + +fun toMultiValue(items: Iterable, collectionFormat: String, map: (item: T) -> String = defaultMultiValueConverter): List { + return when(collectionFormat) { + "multi" -> items.map(map) + else -> listOf(items.joinToString(separator = collectionDelimiter(collectionFormat), transform = map)) + } +} \ No newline at end of file diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt new file mode 100644 index 000000000000..bfd00ac6a2ef --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -0,0 +1,242 @@ +package org.openapitools.client.infrastructure + +import okhttp3.OkHttpClient +import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.FormBody +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull +import okhttp3.ResponseBody +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.Request +import okhttp3.Headers +import okhttp3.Headers.Companion.toHeaders +import okhttp3.MultipartBody +import okhttp3.Call +import okhttp3.Callback +import okhttp3.Response +import okhttp3.internal.EMPTY_REQUEST +import java.io.BufferedWriter +import java.io.File +import java.io.FileWriter +import java.io.IOException +import java.net.URLConnection +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime +import java.time.OffsetDateTime +import java.time.OffsetTime +import java.util.Locale +import com.squareup.moshi.adapter + +open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClient) { + companion object { + protected const val ContentType = "Content-Type" + protected const val Accept = "Accept" + protected const val Authorization = "Authorization" + protected const val JsonMediaType = "application/json" + protected const val FormDataMediaType = "multipart/form-data" + protected const val FormUrlEncMediaType = "application/x-www-form-urlencoded" + protected const val XmlMediaType = "application/xml" + + val apiKey: MutableMap = mutableMapOf() + val apiKeyPrefix: MutableMap = mutableMapOf() + var username: String? = null + var password: String? = null + var accessToken: String? = null + const val baseUrlKey = "org.openapitools.client.baseUrl" + + @JvmStatic + val defaultClient: OkHttpClient by lazy { + builder.build() + } + + @JvmStatic + val builder: OkHttpClient.Builder = OkHttpClient.Builder() + } + + /** + * Guess Content-Type header from the given file (defaults to "application/octet-stream"). + * + * @param file The given file + * @return The guessed Content-Type + */ + protected fun guessContentTypeFromFile(file: File): String { + val contentType = URLConnection.guessContentTypeFromName(file.name) + return contentType ?: "application/octet-stream" + } + + protected inline fun requestBody(content: T, mediaType: String?): RequestBody = + when { + mediaType == FormDataMediaType -> + MultipartBody.Builder() + .setType(MultipartBody.FORM) + .apply { + // content's type *must* be Map> + @Suppress("UNCHECKED_CAST") + (content as Map>).forEach { (name, part) -> + val contentType = part.headers.remove("Content-Type") + val bodies = if (part.body is Iterable<*>) part.body else listOf(part.body) + bodies.forEach { body -> + val headers = part.headers.toMutableMap() + + ("Content-Disposition" to "form-data; name=\"$name\"" + if (body is File) "; filename=\"${body.name}\"" else "") + addPart(headers.toHeaders(), + requestSingleBody(body, contentType)) + } + } + }.build() + else -> requestSingleBody(content, mediaType) + } + + protected inline fun requestSingleBody(content: T, mediaType: String?): RequestBody = + when { + content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull()) + mediaType == FormUrlEncMediaType -> { + FormBody.Builder().apply { + // content's type *must* be Map> + @Suppress("UNCHECKED_CAST") + (content as Map>).forEach { (name, part) -> + add(name, parameterToString(part.body)) + } + }.build() + } + mediaType == null || mediaType.startsWith("application/") && mediaType.endsWith("json") -> + if (content == null) { + EMPTY_REQUEST + } else { + Serializer.moshi.adapter(T::class.java).toJson(content) + .toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull()) + } + mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.") + // TODO: this should be extended with other serializers + else -> throw UnsupportedOperationException("requestBody currently only supports JSON body and File body.") + } + + @OptIn(ExperimentalStdlibApi::class) + protected inline fun responseBody(body: ResponseBody?, mediaType: String? = JsonMediaType): T? { + if(body == null) { + return null + } + if (T::class.java == File::class.java) { + // return tempFile + // Attention: if you are developing an android app that supports API Level 25 and bellow, please check flag supportAndroidApiLevel25AndBelow in https://openapi-generator.tech/docs/generators/kotlin#config-options + val tempFile = java.nio.file.Files.createTempFile("tmp.org.openapitools.client", null).toFile() + tempFile.deleteOnExit() + body.byteStream().use { inputStream -> + tempFile.outputStream().use { tempFileOutputStream -> + inputStream.copyTo(tempFileOutputStream) + } + } + return tempFile as T + } + val bodyContent = body.string() + if (bodyContent.isEmpty()) { + return null + } + return when { + mediaType==null || (mediaType.startsWith("application/") && mediaType.endsWith("json")) -> + Serializer.moshi.adapter().fromJson(bodyContent) + else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.") + } + } + + + protected inline fun request(requestConfig: RequestConfig): ApiResponse { + val httpUrl = baseUrl.toHttpUrlOrNull() ?: throw IllegalStateException("baseUrl is invalid.") + + val url = httpUrl.newBuilder() + .addPathSegments(requestConfig.path.trimStart('/')) + .apply { + requestConfig.query.forEach { query -> + query.value.forEach { queryValue -> + addQueryParameter(query.key, queryValue) + } + } + }.build() + + // take content-type/accept from spec or set to default (application/json) if not defined + if (requestConfig.headers[ContentType].isNullOrEmpty()) { + requestConfig.headers[ContentType] = JsonMediaType + } + if (requestConfig.headers[Accept].isNullOrEmpty()) { + requestConfig.headers[Accept] = JsonMediaType + } + val headers = requestConfig.headers + + if(headers[ContentType].isNullOrEmpty()) { + throw kotlin.IllegalStateException("Missing Content-Type header. This is required.") + } + + if(headers[Accept].isNullOrEmpty()) { + throw kotlin.IllegalStateException("Missing Accept header. This is required.") + } + + // TODO: support multiple contentType options here. + val contentType = (headers[ContentType] as String).substringBefore(";").lowercase(Locale.getDefault()) + + val request = when (requestConfig.method) { + RequestMethod.DELETE -> Request.Builder().url(url).delete(requestBody(requestConfig.body, contentType)) + RequestMethod.GET -> Request.Builder().url(url) + RequestMethod.HEAD -> Request.Builder().url(url).head() + RequestMethod.PATCH -> Request.Builder().url(url).patch(requestBody(requestConfig.body, contentType)) + RequestMethod.PUT -> Request.Builder().url(url).put(requestBody(requestConfig.body, contentType)) + RequestMethod.POST -> Request.Builder().url(url).post(requestBody(requestConfig.body, contentType)) + RequestMethod.OPTIONS -> Request.Builder().url(url).method("OPTIONS", null) + }.apply { + headers.forEach { header -> addHeader(header.key, header.value) } + }.build() + + val response = client.newCall(request).execute() + + val accept = response.header(ContentType)?.substringBefore(";")?.lowercase(Locale.getDefault()) + + // TODO: handle specific mapping types. e.g. Map> + return when { + response.isRedirect -> Redirection( + response.code, + response.headers.toMultimap() + ) + response.isInformational -> Informational( + response.message, + response.code, + response.headers.toMultimap() + ) + response.isSuccessful -> Success( + responseBody(response.body, accept), + response.code, + response.headers.toMultimap() + ) + response.isClientError -> ClientError( + response.message, + response.body?.string(), + response.code, + response.headers.toMultimap() + ) + else -> ServerError( + response.message, + response.body?.string(), + response.code, + response.headers.toMultimap() + ) + } + } + + protected fun parameterToString(value: Any?): String = when (value) { + null -> "" + is Array<*> -> toMultiValue(value, "csv").toString() + is Iterable<*> -> toMultiValue(value, "csv").toString() + is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime -> + parseDateToQueryString(value) + else -> value.toString() + } + + protected inline fun parseDateToQueryString(value : T): String { + /* + .replace("\"", "") converts the json object string to an actual string for the query parameter. + The moshi or gson adapter allows a more generic solution instead of trying to use a native + formatter. It also easily allows to provide a simple way to define a custom date format pattern + inside a gson/moshi adapter. + */ + return Serializer.moshi.adapter(T::class.java).toJson(value).replace("\"", "") + } +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ApiResponse.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ApiResponse.kt new file mode 100644 index 000000000000..20ac25b12500 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ApiResponse.kt @@ -0,0 +1,43 @@ +package org.openapitools.client.infrastructure + +enum class ResponseType { + Success, Informational, Redirection, ClientError, ServerError +} + +interface Response + +abstract class ApiResponse(val responseType: ResponseType): Response { + abstract val statusCode: Int + abstract val headers: Map> +} + +class Success( + val data: T?, + override val statusCode: Int = -1, + override val headers: Map> = mapOf() +): ApiResponse(ResponseType.Success) + +class Informational( + val statusText: String, + override val statusCode: Int = -1, + override val headers: Map> = mapOf() +) : ApiResponse(ResponseType.Informational) + +class Redirection( + override val statusCode: Int = -1, + override val headers: Map> = mapOf() +) : ApiResponse(ResponseType.Redirection) + +class ClientError( + val message: String? = null, + val body: Any? = null, + override val statusCode: Int = -1, + override val headers: Map> = mapOf() +) : ApiResponse(ResponseType.ClientError) + +class ServerError( + val message: String? = null, + val body: Any? = null, + override val statusCode: Int = -1, + override val headers: Map> +): ApiResponse(ResponseType.ServerError) diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt new file mode 100644 index 000000000000..064b57fc6b82 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt @@ -0,0 +1,17 @@ +package org.openapitools.client.infrastructure + +import com.squareup.moshi.FromJson +import com.squareup.moshi.ToJson +import java.math.BigDecimal + +class BigDecimalAdapter { + @ToJson + fun toJson(value: BigDecimal): String { + return value.toPlainString() + } + + @FromJson + fun fromJson(value: String): BigDecimal { + return BigDecimal(value) + } +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt new file mode 100644 index 000000000000..7df6057b4503 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt @@ -0,0 +1,17 @@ +package org.openapitools.client.infrastructure + +import com.squareup.moshi.FromJson +import com.squareup.moshi.ToJson +import java.math.BigInteger + +class BigIntegerAdapter { + @ToJson + fun toJson(value: BigInteger): String { + return value.toString() + } + + @FromJson + fun fromJson(value: String): BigInteger { + return BigInteger(value) + } +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ByteArrayAdapter.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ByteArrayAdapter.kt new file mode 100644 index 000000000000..ff5e2a81ee8c --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ByteArrayAdapter.kt @@ -0,0 +1,12 @@ +package org.openapitools.client.infrastructure + +import com.squareup.moshi.FromJson +import com.squareup.moshi.ToJson + +class ByteArrayAdapter { + @ToJson + fun toJson(data: ByteArray): String = String(data) + + @FromJson + fun fromJson(data: String): ByteArray = data.toByteArray() +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/Errors.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/Errors.kt new file mode 100644 index 000000000000..b5310e71f13c --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/Errors.kt @@ -0,0 +1,18 @@ +@file:Suppress("unused") +package org.openapitools.client.infrastructure + +import java.lang.RuntimeException + +open class ClientException(message: kotlin.String? = null, val statusCode: Int = -1, val response: Response? = null) : RuntimeException(message) { + + companion object { + private const val serialVersionUID: Long = 123L + } +} + +open class ServerException(message: kotlin.String? = null, val statusCode: Int = -1, val response: Response? = null) : RuntimeException(message) { + + companion object { + private const val serialVersionUID: Long = 456L + } +} \ No newline at end of file diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt new file mode 100644 index 000000000000..b2e1654479a0 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt @@ -0,0 +1,19 @@ +package org.openapitools.client.infrastructure + +import com.squareup.moshi.FromJson +import com.squareup.moshi.ToJson +import java.time.LocalDate +import java.time.format.DateTimeFormatter + +class LocalDateAdapter { + @ToJson + fun toJson(value: LocalDate): String { + return DateTimeFormatter.ISO_LOCAL_DATE.format(value) + } + + @FromJson + fun fromJson(value: String): LocalDate { + return LocalDate.parse(value, DateTimeFormatter.ISO_LOCAL_DATE) + } + +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt new file mode 100644 index 000000000000..e082db94811d --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt @@ -0,0 +1,19 @@ +package org.openapitools.client.infrastructure + +import com.squareup.moshi.FromJson +import com.squareup.moshi.ToJson +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter + +class LocalDateTimeAdapter { + @ToJson + fun toJson(value: LocalDateTime): String { + return DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(value) + } + + @FromJson + fun fromJson(value: String): LocalDateTime { + return LocalDateTime.parse(value, DateTimeFormatter.ISO_LOCAL_DATE_TIME) + } + +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/OffsetDateTimeAdapter.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/OffsetDateTimeAdapter.kt new file mode 100644 index 000000000000..87437871a31e --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/OffsetDateTimeAdapter.kt @@ -0,0 +1,19 @@ +package org.openapitools.client.infrastructure + +import com.squareup.moshi.FromJson +import com.squareup.moshi.ToJson +import java.time.OffsetDateTime +import java.time.format.DateTimeFormatter + +class OffsetDateTimeAdapter { + @ToJson + fun toJson(value: OffsetDateTime): String { + return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value) + } + + @FromJson + fun fromJson(value: String): OffsetDateTime { + return OffsetDateTime.parse(value, DateTimeFormatter.ISO_OFFSET_DATE_TIME) + } + +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/PartConfig.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/PartConfig.kt new file mode 100644 index 000000000000..be00e38fbaee --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/PartConfig.kt @@ -0,0 +1,11 @@ +package org.openapitools.client.infrastructure + +/** + * Defines a config object for a given part of a multi-part request. + * NOTE: Headers is a Map because rfc2616 defines + * multi-valued headers as csv-only. + */ +data class PartConfig( + val headers: MutableMap = mutableMapOf(), + val body: T? = null +) diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt new file mode 100644 index 000000000000..7e948e1dd071 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt @@ -0,0 +1,17 @@ +package org.openapitools.client.infrastructure + +/** + * Defines a config object for a given request. + * NOTE: This object doesn't include 'body' because it + * allows for caching of the constructed object + * for many request definitions. + * NOTE: Headers is a Map because rfc2616 defines + * multi-valued headers as csv-only. + */ +data class RequestConfig( + val method: RequestMethod, + val path: String, + val headers: MutableMap = mutableMapOf(), + val query: MutableMap> = mutableMapOf(), + val body: T? = null +) \ No newline at end of file diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/RequestMethod.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/RequestMethod.kt new file mode 100644 index 000000000000..931b12b8bd7a --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/RequestMethod.kt @@ -0,0 +1,8 @@ +package org.openapitools.client.infrastructure + +/** + * Provides enumerated HTTP verbs + */ +enum class RequestMethod { + GET, DELETE, HEAD, OPTIONS, PATCH, POST, PUT +} \ No newline at end of file diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ResponseExtensions.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ResponseExtensions.kt new file mode 100644 index 000000000000..9bd2790dc144 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/ResponseExtensions.kt @@ -0,0 +1,24 @@ +package org.openapitools.client.infrastructure + +import okhttp3.Response + +/** + * Provides an extension to evaluation whether the response is a 1xx code + */ +val Response.isInformational : Boolean get() = this.code in 100..199 + +/** + * Provides an extension to evaluation whether the response is a 3xx code + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +val Response.isRedirect : Boolean get() = this.code in 300..399 + +/** + * Provides an extension to evaluation whether the response is a 4xx code + */ +val Response.isClientError : Boolean get() = this.code in 400..499 + +/** + * Provides an extension to evaluation whether the response is a 5xx (Standard) through 999 (non-standard) code + */ +val Response.isServerError : Boolean get() = this.code in 500..999 diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt new file mode 100644 index 000000000000..e22592e47d74 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt @@ -0,0 +1,23 @@ +package org.openapitools.client.infrastructure + +import com.squareup.moshi.Moshi +import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory + +object Serializer { + @JvmStatic + val moshiBuilder: Moshi.Builder = Moshi.Builder() + .add(OffsetDateTimeAdapter()) + .add(LocalDateTimeAdapter()) + .add(LocalDateAdapter()) + .add(UUIDAdapter()) + .add(ByteArrayAdapter()) + .add(URIAdapter()) + .add(KotlinJsonAdapterFactory()) + .add(BigDecimalAdapter()) + .add(BigIntegerAdapter()) + + @JvmStatic + val moshi: Moshi by lazy { + moshiBuilder.build() + } +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt new file mode 100644 index 000000000000..927522757da9 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt @@ -0,0 +1,13 @@ +package org.openapitools.client.infrastructure + +import com.squareup.moshi.FromJson +import com.squareup.moshi.ToJson +import java.net.URI + +class URIAdapter { + @ToJson + fun toJson(uri: URI) = uri.toString() + + @FromJson + fun fromJson(s: String): URI = URI.create(s) +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt new file mode 100644 index 000000000000..7ccf7dc25d2d --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt @@ -0,0 +1,13 @@ +package org.openapitools.client.infrastructure + +import com.squareup.moshi.FromJson +import com.squareup.moshi.ToJson +import java.util.UUID + +class UUIDAdapter { + @ToJson + fun toJson(uuid: UUID) = uuid.toString() + + @FromJson + fun fromJson(s: String): UUID = UUID.fromString(s) +} diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/ModelWithNullableObjectProperty.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/ModelWithNullableObjectProperty.kt new file mode 100644 index 000000000000..99b1a8f71e85 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/ModelWithNullableObjectProperty.kt @@ -0,0 +1,63 @@ +/** + * Title + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import org.openapitools.client.models.ModelWithNullableObjectPropertyNonNullableProperty +import org.openapitools.client.models.ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes +import org.openapitools.client.models.PropertyType + +import com.squareup.moshi.Json +import java.io.Serializable + +/** + * + * + * @param propertyName + * @param propertyName30 + * @param propertyName31 + * @param nonNullableProperty + * @param propertyWithNullAndTwoTypes + */ + +data class ModelWithNullableObjectProperty ( + + @Json(name = "propertyName") + val propertyName: PropertyType? = null, + + @Json(name = "propertyName30") + val propertyName30: PropertyType? = null, + + @Json(name = "propertyName31") + val propertyName31: PropertyType? = null, + + @Json(name = "nonNullableProperty") + val nonNullableProperty: ModelWithNullableObjectPropertyNonNullableProperty? = null, + + @Json(name = "propertyWithNullAndTwoTypes") + val propertyWithNullAndTwoTypes: ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes? = null + +) : Serializable { + companion object { + private const val serialVersionUID: Long = 123 + } + +} + diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/ModelWithNullableObjectPropertyNonNullableProperty.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/ModelWithNullableObjectPropertyNonNullableProperty.kt new file mode 100644 index 000000000000..3da0d02cc9d8 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/ModelWithNullableObjectPropertyNonNullableProperty.kt @@ -0,0 +1,38 @@ +/** + * Title + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + + +import com.squareup.moshi.Json +import java.io.Serializable + +/** + * + * + */ + +data class ModelWithNullableObjectPropertyNonNullableProperty ( + +) : Serializable companion object { + private const val serialVersionUID: Long = 123 + } + + diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.kt new file mode 100644 index 000000000000..3764f9c1ca70 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.kt @@ -0,0 +1,50 @@ +/** + * Title + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import org.openapitools.client.models.OtherPropertyType +import org.openapitools.client.models.PropertyType + +import com.squareup.moshi.Json +import java.io.Serializable + +/** + * + * + * @param foo + * @param bar + */ + +data class ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes ( + + @Json(name = "foo") + val foo: kotlin.String? = null, + + @Json(name = "bar") + val bar: kotlin.String? = null + +) : Serializable { + companion object { + private const val serialVersionUID: Long = 123 + } + +} + diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/OtherPropertyType.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/OtherPropertyType.kt new file mode 100644 index 000000000000..8a3e99ac4e4d --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/OtherPropertyType.kt @@ -0,0 +1,44 @@ +/** + * Title + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + + +import com.squareup.moshi.Json +import java.io.Serializable + +/** + * + * + * @param bar + */ + +data class OtherPropertyType ( + + @Json(name = "bar") + val bar: kotlin.String? = null + +) : Serializable { + companion object { + private const val serialVersionUID: Long = 123 + } + +} + diff --git a/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/PropertyType.kt b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/PropertyType.kt new file mode 100644 index 000000000000..379f27b4d021 --- /dev/null +++ b/samples/client/petstore/kotlin-nullable-object-propery/src/main/kotlin/org/openapitools/client/models/PropertyType.kt @@ -0,0 +1,44 @@ +/** + * Title + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + + +import com.squareup.moshi.Json +import java.io.Serializable + +/** + * + * + * @param foo + */ + +data class PropertyType ( + + @Json(name = "foo") + val foo: kotlin.String? = null + +) : Serializable { + companion object { + private const val serialVersionUID: Long = 123 + } + +} + diff --git a/samples/client/petstore/php/nullable-object-property-php/.gitignore b/samples/client/petstore/php/nullable-object-property-php/.gitignore new file mode 100644 index 000000000000..9f1681c2be8d --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/.gitignore @@ -0,0 +1,15 @@ +# ref: https://github.com/github/gitignore/blob/master/Composer.gitignore + +composer.phar +/vendor/ + +# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control +# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file +# composer.lock + +# php-cs-fixer cache +.php_cs.cache +.php-cs-fixer.cache + +# PHPUnit cache +.phpunit.result.cache diff --git a/samples/client/petstore/php/nullable-object-property-php/.openapi-generator-ignore b/samples/client/petstore/php/nullable-object-property-php/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore/php/nullable-object-property-php/.openapi-generator/FILES b/samples/client/petstore/php/nullable-object-property-php/.openapi-generator/FILES new file mode 100644 index 000000000000..b565997dca05 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/.openapi-generator/FILES @@ -0,0 +1,24 @@ +.gitignore +.php-cs-fixer.dist.php +.travis.yml +README.md +composer.json +docs/Api/DefaultApi.md +docs/Model/ModelWithNullableObjectProperty.md +docs/Model/ModelWithNullableObjectPropertyNonNullableProperty.md +docs/Model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md +docs/Model/OtherPropertyType.md +docs/Model/PropertyType.md +git_push.sh +lib/Api/DefaultApi.php +lib/ApiException.php +lib/Configuration.php +lib/HeaderSelector.php +lib/Model/ModelInterface.php +lib/Model/ModelWithNullableObjectProperty.php +lib/Model/ModelWithNullableObjectPropertyNonNullableProperty.php +lib/Model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.php +lib/Model/OtherPropertyType.php +lib/Model/PropertyType.php +lib/ObjectSerializer.php +phpunit.xml.dist diff --git a/samples/client/petstore/php/nullable-object-property-php/.openapi-generator/VERSION b/samples/client/petstore/php/nullable-object-property-php/.openapi-generator/VERSION new file mode 100644 index 000000000000..66672d4e9d31 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/.openapi-generator/VERSION @@ -0,0 +1 @@ +6.1.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/php/nullable-object-property-php/.php-cs-fixer.dist.php b/samples/client/petstore/php/nullable-object-property-php/.php-cs-fixer.dist.php new file mode 100644 index 000000000000..af9cf39fddb0 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/.php-cs-fixer.dist.php @@ -0,0 +1,29 @@ +in(__DIR__) + ->exclude('vendor') + ->exclude('test') + ->exclude('tests') +; + +$config = new PhpCsFixer\Config(); +return $config->setRules([ + '@PSR12' => true, + 'phpdoc_order' => true, + 'array_syntax' => [ 'syntax' => 'short' ], + 'strict_comparison' => true, + 'strict_param' => true, + 'no_trailing_whitespace' => false, + 'no_trailing_whitespace_in_comment' => false, + 'braces' => false, + 'single_blank_line_at_eof' => false, + 'blank_line_after_namespace' => false, + 'no_leading_import_slash' => false, + ]) + ->setFinder($finder) +; diff --git a/samples/client/petstore/php/nullable-object-property-php/.travis.yml b/samples/client/petstore/php/nullable-object-property-php/.travis.yml new file mode 100644 index 000000000000..667b81565308 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/.travis.yml @@ -0,0 +1,8 @@ +language: php +# Bionic environment has preinstalled PHP from 7.1 to 7.4 +# https://docs.travis-ci.com/user/reference/bionic/#php-support +dist: bionic +php: + - 7.4 +before_install: "composer install" +script: "vendor/bin/phpunit" diff --git a/samples/client/petstore/php/nullable-object-property-php/README.md b/samples/client/petstore/php/nullable-object-property-php/README.md new file mode 100644 index 000000000000..9a06571ddd61 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/README.md @@ -0,0 +1,104 @@ +# OpenAPIClient-php + +No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + + +## Installation & Usage + +### Requirements + +PHP 7.4 and later. +Should also work with PHP 8.0. + +### Composer + +To install the bindings via [Composer](https://getcomposer.org/), add the following to `composer.json`: + +```json +{ + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/GIT_USER_ID/GIT_REPO_ID.git" + } + ], + "require": { + "GIT_USER_ID/GIT_REPO_ID": "*@dev" + } +} +``` + +Then run `composer install` + +### Manual Installation + +Download the files and include `autoload.php`: + +```php +operation(); + print_r($result); +} catch (Exception $e) { + echo 'Exception when calling DefaultApi->operation: ', $e->getMessage(), PHP_EOL; +} + +``` + +## API Endpoints + +All URIs are relative to *http://localhost* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*DefaultApi* | [**operation**](docs/Api/DefaultApi.md#operation) | **GET** / | + +## Models + +- [ModelWithNullableObjectProperty](docs/Model/ModelWithNullableObjectProperty.md) +- [ModelWithNullableObjectPropertyNonNullableProperty](docs/Model/ModelWithNullableObjectPropertyNonNullableProperty.md) +- [ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes](docs/Model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md) +- [OtherPropertyType](docs/Model/OtherPropertyType.md) +- [PropertyType](docs/Model/PropertyType.md) + +## Authorization +All endpoints do not require authorization. +## Tests + +To run the tests, use: + +```bash +composer install +vendor/bin/phpunit +``` + +## Author + + + +## About this package + +This PHP package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: `latest` +- Build package: `org.openapitools.codegen.languages.PhpClientCodegen` diff --git a/samples/client/petstore/php/nullable-object-property-php/composer.json b/samples/client/petstore/php/nullable-object-property-php/composer.json new file mode 100644 index 000000000000..cccbe610e36b --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/composer.json @@ -0,0 +1,38 @@ +{ + "description": "No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)", + "keywords": [ + "openapitools", + "openapi-generator", + "openapi", + "php", + "sdk", + "rest", + "api" + ], + "homepage": "https://openapi-generator.tech", + "license": "unlicense", + "authors": [ + { + "name": "OpenAPI-Generator contributors", + "homepage": "https://openapi-generator.tech" + } + ], + "require": { + "php": "^7.4 || ^8.0", + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "guzzlehttp/guzzle": "^7.3", + "guzzlehttp/psr7": "^1.7 || ^2.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.0 || ^9.0", + "friendsofphp/php-cs-fixer": "^3.5" + }, + "autoload": { + "psr-4": { "OpenAPI\\Client\\" : "lib/" } + }, + "autoload-dev": { + "psr-4": { "OpenAPI\\Client\\Test\\" : "test/" } + } +} diff --git a/samples/client/petstore/php/nullable-object-property-php/docs/Api/DefaultApi.md b/samples/client/petstore/php/nullable-object-property-php/docs/Api/DefaultApi.md new file mode 100644 index 000000000000..7136f147d54f --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/docs/Api/DefaultApi.md @@ -0,0 +1,59 @@ +# OpenAPI\Client\DefaultApi + +All URIs are relative to http://localhost, except if the operation defines another base path. + +| Method | HTTP request | Description | +| ------------- | ------------- | ------------- | +| [**operation()**](DefaultApi.md#operation) | **GET** / | | + + +## `operation()` + +```php +operation(): \OpenAPI\Client\Model\ModelWithNullableObjectProperty +``` + + + +### Example + +```php +operation(); + print_r($result); +} catch (Exception $e) { + echo 'Exception when calling DefaultApi->operation: ', $e->getMessage(), PHP_EOL; +} +``` + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +[**\OpenAPI\Client\Model\ModelWithNullableObjectProperty**](../Model/ModelWithNullableObjectProperty.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: `application/json` + +[[Back to top]](#) [[Back to API list]](../../README.md#endpoints) +[[Back to Model list]](../../README.md#models) +[[Back to README]](../../README.md) diff --git a/samples/client/petstore/php/nullable-object-property-php/docs/Model/ModelWithNullableObjectProperty.md b/samples/client/petstore/php/nullable-object-property-php/docs/Model/ModelWithNullableObjectProperty.md new file mode 100644 index 000000000000..85d9b781cdc2 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/docs/Model/ModelWithNullableObjectProperty.md @@ -0,0 +1,13 @@ +# # ModelWithNullableObjectProperty + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**property_name** | [**\OpenAPI\Client\Model\PropertyType**](PropertyType.md) | | [optional] +**property_name30** | [**\OpenAPI\Client\Model\PropertyType**](PropertyType.md) | | [optional] +**property_name31** | [**\OpenAPI\Client\Model\PropertyType**](PropertyType.md) | | [optional] +**non_nullable_property** | [**\OpenAPI\Client\Model\ModelWithNullableObjectPropertyNonNullableProperty**](ModelWithNullableObjectPropertyNonNullableProperty.md) | | [optional] +**property_with_null_and_two_types** | [**\OpenAPI\Client\Model\ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes**](ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md) | | [optional] + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/samples/client/petstore/php/nullable-object-property-php/docs/Model/ModelWithNullableObjectPropertyNonNullableProperty.md b/samples/client/petstore/php/nullable-object-property-php/docs/Model/ModelWithNullableObjectPropertyNonNullableProperty.md new file mode 100644 index 000000000000..b65ab88861bd --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/docs/Model/ModelWithNullableObjectPropertyNonNullableProperty.md @@ -0,0 +1,8 @@ +# # ModelWithNullableObjectPropertyNonNullableProperty + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/samples/client/petstore/php/nullable-object-property-php/docs/Model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md b/samples/client/petstore/php/nullable-object-property-php/docs/Model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md new file mode 100644 index 000000000000..30ea2a999085 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/docs/Model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.md @@ -0,0 +1,10 @@ +# # ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**foo** | **string** | | [optional] +**bar** | **string** | | [optional] + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/samples/client/petstore/php/nullable-object-property-php/docs/Model/OtherPropertyType.md b/samples/client/petstore/php/nullable-object-property-php/docs/Model/OtherPropertyType.md new file mode 100644 index 000000000000..cb036d2a1b15 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/docs/Model/OtherPropertyType.md @@ -0,0 +1,9 @@ +# # OtherPropertyType + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**bar** | **string** | | [optional] + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/samples/client/petstore/php/nullable-object-property-php/docs/Model/PropertyType.md b/samples/client/petstore/php/nullable-object-property-php/docs/Model/PropertyType.md new file mode 100644 index 000000000000..1a063f11281e --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/docs/Model/PropertyType.md @@ -0,0 +1,9 @@ +# # PropertyType + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**foo** | **string** | | [optional] + +[[Back to Model list]](../../README.md#models) [[Back to API list]](../../README.md#endpoints) [[Back to README]](../../README.md) diff --git a/samples/client/petstore/php/nullable-object-property-php/git_push.sh b/samples/client/petstore/php/nullable-object-property-php/git_push.sh new file mode 100644 index 000000000000..f53a75d4fabe --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/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="github.com" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/samples/client/petstore/php/nullable-object-property-php/lib/Api/DefaultApi.php b/samples/client/petstore/php/nullable-object-property-php/lib/Api/DefaultApi.php new file mode 100644 index 000000000000..5af269f41223 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/lib/Api/DefaultApi.php @@ -0,0 +1,390 @@ +client = $client ?: new Client(); + $this->config = $config ?: new Configuration(); + $this->headerSelector = $selector ?: new HeaderSelector(); + $this->hostIndex = $hostIndex; + } + + /** + * Set the host index + * + * @param int $hostIndex Host index (required) + */ + public function setHostIndex($hostIndex): void + { + $this->hostIndex = $hostIndex; + } + + /** + * Get the host index + * + * @return int Host index + */ + public function getHostIndex() + { + return $this->hostIndex; + } + + /** + * @return Configuration + */ + public function getConfig() + { + return $this->config; + } + + /** + * Operation operation + * + * + * @throws \OpenAPI\Client\ApiException on non-2xx response + * @throws \InvalidArgumentException + * @return \OpenAPI\Client\Model\ModelWithNullableObjectProperty + */ + public function operation() + { + list($response) = $this->operationWithHttpInfo(); + return $response; + } + + /** + * Operation operationWithHttpInfo + * + * + * @throws \OpenAPI\Client\ApiException on non-2xx response + * @throws \InvalidArgumentException + * @return array of \OpenAPI\Client\Model\ModelWithNullableObjectProperty, HTTP status code, HTTP response headers (array of strings) + */ + public function operationWithHttpInfo() + { + $request = $this->operationRequest(); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? (string) $e->getResponse()->getBody() : null + ); + } catch (ConnectException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + (int) $e->getCode(), + null, + null + ); + } + + $statusCode = $response->getStatusCode(); + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + (string) $request->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + + switch($statusCode) { + case 200: + if ('\OpenAPI\Client\Model\ModelWithNullableObjectProperty' === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ('\OpenAPI\Client\Model\ModelWithNullableObjectProperty' !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, '\OpenAPI\Client\Model\ModelWithNullableObjectProperty', []), + $response->getStatusCode(), + $response->getHeaders() + ]; + } + + $returnType = '\OpenAPI\Client\Model\ModelWithNullableObjectProperty'; + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + + } catch (ApiException $e) { + switch ($e->getCode()) { + case 200: + $data = ObjectSerializer::deserialize( + $e->getResponseBody(), + '\OpenAPI\Client\Model\ModelWithNullableObjectProperty', + $e->getResponseHeaders() + ); + $e->setResponseObject($data); + break; + } + throw $e; + } + } + + /** + * Operation operationAsync + * + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function operationAsync() + { + return $this->operationAsyncWithHttpInfo() + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation operationAsyncWithHttpInfo + * + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function operationAsyncWithHttpInfo() + { + $returnType = '\OpenAPI\Client\Model\ModelWithNullableObjectProperty'; + $request = $this->operationRequest(); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + if ($returnType === '\SplFileObject') { + $content = $response->getBody(); //stream goes to serializer + } else { + $content = (string) $response->getBody(); + if ($returnType !== 'string') { + $content = json_decode($content); + } + } + + return [ + ObjectSerializer::deserialize($content, $returnType, []), + $response->getStatusCode(), + $response->getHeaders() + ]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + (string) $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'operation' + * + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + public function operationRequest() + { + + $resourcePath = '/'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + + + + + if ($multipart) { + $headers = $this->headerSelector->selectHeadersForMultipart( + ['application/json'] + ); + } else { + $headers = $this->headerSelector->selectHeaders( + ['application/json'], + [] + ); + } + + // for model (json/xml) + if (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue]; + foreach ($formParamValueItems as $formParamValueItem) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValueItem + ]; + } + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif ($headers['Content-Type'] === 'application/json') { + $httpBody = \GuzzleHttp\json_encode($formParams); + + } else { + // for HTTP post (form) + $httpBody = ObjectSerializer::buildQuery($formParams); + } + } + + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $operationHost = $this->config->getHost(); + $query = ObjectSerializer::buildQuery($queryParams); + return new Request( + 'GET', + $operationHost . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Create http client option + * + * @throws \RuntimeException on file opening failure + * @return array of http client options + */ + protected function createHttpClientOption() + { + $options = []; + if ($this->config->getDebug()) { + $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a'); + if (!$options[RequestOptions::DEBUG]) { + throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile()); + } + } + + return $options; + } +} diff --git a/samples/client/petstore/php/nullable-object-property-php/lib/ApiException.php b/samples/client/petstore/php/nullable-object-property-php/lib/ApiException.php new file mode 100644 index 000000000000..58aacebe7f4c --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/lib/ApiException.php @@ -0,0 +1,119 @@ +responseHeaders = $responseHeaders; + $this->responseBody = $responseBody; + } + + /** + * Gets the HTTP response header + * + * @return string[]|null HTTP response header + */ + public function getResponseHeaders() + { + return $this->responseHeaders; + } + + /** + * Gets the HTTP body of the server response either as Json or string + * + * @return \stdClass|string|null HTTP body of the server response either as \stdClass or string + */ + public function getResponseBody() + { + return $this->responseBody; + } + + /** + * Sets the deserialized response object (during deserialization) + * + * @param mixed $obj Deserialized response object + * + * @return void + */ + public function setResponseObject($obj) + { + $this->responseObject = $obj; + } + + /** + * Gets the deserialized response object (during deserialization) + * + * @return mixed the deserialized response object + */ + public function getResponseObject() + { + return $this->responseObject; + } +} diff --git a/samples/client/petstore/php/nullable-object-property-php/lib/Configuration.php b/samples/client/petstore/php/nullable-object-property-php/lib/Configuration.php new file mode 100644 index 000000000000..690b222f4349 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/lib/Configuration.php @@ -0,0 +1,531 @@ +tempFolderPath = sys_get_temp_dir(); + } + + /** + * Sets API key + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * @param string $key API key or token + * + * @return $this + */ + public function setApiKey($apiKeyIdentifier, $key) + { + $this->apiKeys[$apiKeyIdentifier] = $key; + return $this; + } + + /** + * Gets API key + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * + * @return null|string API key or token + */ + public function getApiKey($apiKeyIdentifier) + { + return isset($this->apiKeys[$apiKeyIdentifier]) ? $this->apiKeys[$apiKeyIdentifier] : null; + } + + /** + * Sets the prefix for API key (e.g. Bearer) + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * @param string $prefix API key prefix, e.g. Bearer + * + * @return $this + */ + public function setApiKeyPrefix($apiKeyIdentifier, $prefix) + { + $this->apiKeyPrefixes[$apiKeyIdentifier] = $prefix; + return $this; + } + + /** + * Gets API key prefix + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * + * @return null|string + */ + public function getApiKeyPrefix($apiKeyIdentifier) + { + return isset($this->apiKeyPrefixes[$apiKeyIdentifier]) ? $this->apiKeyPrefixes[$apiKeyIdentifier] : null; + } + + /** + * Sets the access token for OAuth + * + * @param string $accessToken Token for OAuth + * + * @return $this + */ + public function setAccessToken($accessToken) + { + $this->accessToken = $accessToken; + return $this; + } + + /** + * Gets the access token for OAuth + * + * @return string Access token for OAuth + */ + public function getAccessToken() + { + return $this->accessToken; + } + + /** + * Sets boolean format for query string. + * + * @param string $booleanFormatForQueryString Boolean format for query string + * + * @return $this + */ + public function setBooleanFormatForQueryString(string $booleanFormat) + { + $this->booleanFormatForQueryString = $booleanFormat; + + return $this; + } + + /** + * Gets boolean format for query string. + * + * @return string Boolean format for query string + */ + public function getBooleanFormatForQueryString(): string + { + return $this->booleanFormatForQueryString; + } + + /** + * Sets the username for HTTP basic authentication + * + * @param string $username Username for HTTP basic authentication + * + * @return $this + */ + public function setUsername($username) + { + $this->username = $username; + return $this; + } + + /** + * Gets the username for HTTP basic authentication + * + * @return string Username for HTTP basic authentication + */ + public function getUsername() + { + return $this->username; + } + + /** + * Sets the password for HTTP basic authentication + * + * @param string $password Password for HTTP basic authentication + * + * @return $this + */ + public function setPassword($password) + { + $this->password = $password; + return $this; + } + + /** + * Gets the password for HTTP basic authentication + * + * @return string Password for HTTP basic authentication + */ + public function getPassword() + { + return $this->password; + } + + /** + * Sets the host + * + * @param string $host Host + * + * @return $this + */ + public function setHost($host) + { + $this->host = $host; + return $this; + } + + /** + * Gets the host + * + * @return string Host + */ + public function getHost() + { + return $this->host; + } + + /** + * Sets the user agent of the api client + * + * @param string $userAgent the user agent of the api client + * + * @throws \InvalidArgumentException + * @return $this + */ + public function setUserAgent($userAgent) + { + if (!is_string($userAgent)) { + throw new \InvalidArgumentException('User-agent must be a string.'); + } + + $this->userAgent = $userAgent; + return $this; + } + + /** + * Gets the user agent of the api client + * + * @return string user agent + */ + public function getUserAgent() + { + return $this->userAgent; + } + + /** + * Sets debug flag + * + * @param bool $debug Debug flag + * + * @return $this + */ + public function setDebug($debug) + { + $this->debug = $debug; + return $this; + } + + /** + * Gets the debug flag + * + * @return bool + */ + public function getDebug() + { + return $this->debug; + } + + /** + * Sets the debug file + * + * @param string $debugFile Debug file + * + * @return $this + */ + public function setDebugFile($debugFile) + { + $this->debugFile = $debugFile; + return $this; + } + + /** + * Gets the debug file + * + * @return string + */ + public function getDebugFile() + { + return $this->debugFile; + } + + /** + * Sets the temp folder path + * + * @param string $tempFolderPath Temp folder path + * + * @return $this + */ + public function setTempFolderPath($tempFolderPath) + { + $this->tempFolderPath = $tempFolderPath; + return $this; + } + + /** + * Gets the temp folder path + * + * @return string Temp folder path + */ + public function getTempFolderPath() + { + return $this->tempFolderPath; + } + + /** + * Gets the default configuration instance + * + * @return Configuration + */ + public static function getDefaultConfiguration() + { + if (self::$defaultConfiguration === null) { + self::$defaultConfiguration = new Configuration(); + } + + return self::$defaultConfiguration; + } + + /** + * Sets the default configuration instance + * + * @param Configuration $config An instance of the Configuration Object + * + * @return void + */ + public static function setDefaultConfiguration(Configuration $config) + { + self::$defaultConfiguration = $config; + } + + /** + * Gets the essential information for debugging + * + * @return string The report for debugging + */ + public static function toDebugReport() + { + $report = 'PHP SDK (OpenAPI\Client) Debug Report:' . PHP_EOL; + $report .= ' OS: ' . php_uname() . PHP_EOL; + $report .= ' PHP Version: ' . PHP_VERSION . PHP_EOL; + $report .= ' The version of the OpenAPI document: latest' . PHP_EOL; + $report .= ' Temp Folder Path: ' . self::getDefaultConfiguration()->getTempFolderPath() . PHP_EOL; + + return $report; + } + + /** + * Get API key (with prefix if set) + * + * @param string $apiKeyIdentifier name of apikey + * + * @return null|string API key with the prefix + */ + public function getApiKeyWithPrefix($apiKeyIdentifier) + { + $prefix = $this->getApiKeyPrefix($apiKeyIdentifier); + $apiKey = $this->getApiKey($apiKeyIdentifier); + + if ($apiKey === null) { + return null; + } + + if ($prefix === null) { + $keyWithPrefix = $apiKey; + } else { + $keyWithPrefix = $prefix . ' ' . $apiKey; + } + + return $keyWithPrefix; + } + + /** + * Returns an array of host settings + * + * @return array an array of host settings + */ + public function getHostSettings() + { + return [ + [ + "url" => "", + "description" => "No description provided", + ] + ]; + } + + /** + * Returns URL based on host settings, index and variables + * + * @param array $hostSettings array of host settings, generated from getHostSettings() or equivalent from the API clients + * @param int $hostIndex index of the host settings + * @param array|null $variables hash of variable and the corresponding value (optional) + * @return string URL based on host settings + */ + public static function getHostString(array $hostsSettings, $hostIndex, array $variables = null) + { + if (null === $variables) { + $variables = []; + } + + // check array index out of bound + if ($hostIndex < 0 || $hostIndex >= count($hostsSettings)) { + throw new \InvalidArgumentException("Invalid index $hostIndex when selecting the host. Must be less than ".count($hostsSettings)); + } + + $host = $hostsSettings[$hostIndex]; + $url = $host["url"]; + + // go through variable and assign a value + foreach ($host["variables"] ?? [] as $name => $variable) { + if (array_key_exists($name, $variables)) { // check to see if it's in the variables provided by the user + if (!isset($variable['enum_values']) || in_array($variables[$name], $variable["enum_values"], true)) { // check to see if the value is in the enum + $url = str_replace("{".$name."}", $variables[$name], $url); + } else { + throw new \InvalidArgumentException("The variable `$name` in the host URL has invalid value ".$variables[$name].". Must be ".join(',', $variable["enum_values"])."."); + } + } else { + // use default value + $url = str_replace("{".$name."}", $variable["default_value"], $url); + } + } + + return $url; + } + + /** + * Returns URL based on the index and variables + * + * @param int $index index of the host settings + * @param array|null $variables hash of variable and the corresponding value (optional) + * @return string URL based on host settings + */ + public function getHostFromSettings($index, $variables = null) + { + return self::getHostString($this->getHostSettings(), $index, $variables); + } +} diff --git a/samples/client/petstore/php/nullable-object-property-php/lib/HeaderSelector.php b/samples/client/petstore/php/nullable-object-property-php/lib/HeaderSelector.php new file mode 100644 index 000000000000..a9e1133576f9 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/lib/HeaderSelector.php @@ -0,0 +1,107 @@ +selectAcceptHeader($accept); + if ($accept !== null) { + $headers['Accept'] = $accept; + } + + $headers['Content-Type'] = $this->selectContentTypeHeader($contentTypes); + return $headers; + } + + /** + * @param string[] $accept + * @return array + */ + public function selectHeadersForMultipart($accept) + { + $headers = $this->selectHeaders($accept, []); + + unset($headers['Content-Type']); + return $headers; + } + + /** + * Return the header 'Accept' based on an array of Accept provided + * + * @param string[] $accept Array of header + * + * @return null|string Accept (e.g. application/json) + */ + private function selectAcceptHeader($accept) + { + if (count($accept) === 0 || (count($accept) === 1 && $accept[0] === '')) { + return null; + } elseif ($jsonAccept = preg_grep('~(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$~', $accept)) { + return implode(',', $jsonAccept); + } else { + return implode(',', $accept); + } + } + + /** + * Return the content type based on an array of content-type provided + * + * @param string[] $contentType Array fo content-type + * + * @return string Content-Type (e.g. application/json) + */ + private function selectContentTypeHeader($contentType) + { + if (count($contentType) === 0 || (count($contentType) === 1 && $contentType[0] === '')) { + return 'application/json'; + } elseif (preg_grep("/application\/json/i", $contentType)) { + return 'application/json'; + } else { + return implode(',', $contentType); + } + } +} diff --git a/samples/client/petstore/php/nullable-object-property-php/lib/Model/ModelInterface.php b/samples/client/petstore/php/nullable-object-property-php/lib/Model/ModelInterface.php new file mode 100644 index 000000000000..535242859f03 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/lib/Model/ModelInterface.php @@ -0,0 +1,111 @@ + + */ +class ModelWithNullableObjectProperty implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'ModelWithNullableObjectProperty'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'property_name' => '\OpenAPI\Client\Model\PropertyType', + 'property_name30' => '\OpenAPI\Client\Model\PropertyType', + 'property_name31' => '\OpenAPI\Client\Model\PropertyType', + 'non_nullable_property' => '\OpenAPI\Client\Model\ModelWithNullableObjectPropertyNonNullableProperty', + 'property_with_null_and_two_types' => '\OpenAPI\Client\Model\ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'property_name' => null, + 'property_name30' => null, + 'property_name31' => null, + 'non_nullable_property' => null, + 'property_with_null_and_two_types' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'property_name' => false, + 'property_name30' => true, + 'property_name31' => true, + 'non_nullable_property' => false, + 'property_with_null_and_two_types' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'property_name' => 'propertyName', + 'property_name30' => 'propertyName30', + 'property_name31' => 'propertyName31', + 'non_nullable_property' => 'nonNullableProperty', + 'property_with_null_and_two_types' => 'propertyWithNullAndTwoTypes' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'property_name' => 'setPropertyName', + 'property_name30' => 'setPropertyName30', + 'property_name31' => 'setPropertyName31', + 'non_nullable_property' => 'setNonNullableProperty', + 'property_with_null_and_two_types' => 'setPropertyWithNullAndTwoTypes' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'property_name' => 'getPropertyName', + 'property_name30' => 'getPropertyName30', + 'property_name31' => 'getPropertyName31', + 'non_nullable_property' => 'getNonNullableProperty', + 'property_with_null_and_two_types' => 'getPropertyWithNullAndTwoTypes' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[] $data Associated array of property values + * initializing the model + */ + public function __construct(array $data = null) + { + $this->setIfExists('property_name', $data ?? [], null); + $this->setIfExists('property_name30', $data ?? [], null); + $this->setIfExists('property_name31', $data ?? [], null); + $this->setIfExists('non_nullable_property', $data ?? [], null); + $this->setIfExists('property_with_null_and_two_types', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets property_name + * + * @return \OpenAPI\Client\Model\PropertyType|null + */ + public function getPropertyName() + { + return $this->container['property_name']; + } + + /** + * Sets property_name + * + * @param \OpenAPI\Client\Model\PropertyType|null $property_name property_name + * + * @return self + */ + public function setPropertyName($property_name) + { + + if (is_null($property_name)) { + throw new \InvalidArgumentException('non-nullable property_name cannot be null'); + } + + $this->container['property_name'] = $property_name; + + return $this; + } + + /** + * Gets property_name30 + * + * @return \OpenAPI\Client\Model\PropertyType|null + */ + public function getPropertyName30() + { + return $this->container['property_name30']; + } + + /** + * Sets property_name30 + * + * @param \OpenAPI\Client\Model\PropertyType|null $property_name30 property_name30 + * + * @return self + */ + public function setPropertyName30($property_name30) + { + + if (is_null($property_name30)) { + array_push($this->openAPINullablesSetToNull, 'property_name30'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('property_name30', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + + $this->container['property_name30'] = $property_name30; + + return $this; + } + + /** + * Gets property_name31 + * + * @return \OpenAPI\Client\Model\PropertyType|null + */ + public function getPropertyName31() + { + return $this->container['property_name31']; + } + + /** + * Sets property_name31 + * + * @param \OpenAPI\Client\Model\PropertyType|null $property_name31 property_name31 + * + * @return self + */ + public function setPropertyName31($property_name31) + { + + if (is_null($property_name31)) { + array_push($this->openAPINullablesSetToNull, 'property_name31'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('property_name31', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + + $this->container['property_name31'] = $property_name31; + + return $this; + } + + /** + * Gets non_nullable_property + * + * @return \OpenAPI\Client\Model\ModelWithNullableObjectPropertyNonNullableProperty|null + */ + public function getNonNullableProperty() + { + return $this->container['non_nullable_property']; + } + + /** + * Sets non_nullable_property + * + * @param \OpenAPI\Client\Model\ModelWithNullableObjectPropertyNonNullableProperty|null $non_nullable_property non_nullable_property + * + * @return self + */ + public function setNonNullableProperty($non_nullable_property) + { + + if (is_null($non_nullable_property)) { + throw new \InvalidArgumentException('non-nullable non_nullable_property cannot be null'); + } + + $this->container['non_nullable_property'] = $non_nullable_property; + + return $this; + } + + /** + * Gets property_with_null_and_two_types + * + * @return \OpenAPI\Client\Model\ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes|null + */ + public function getPropertyWithNullAndTwoTypes() + { + return $this->container['property_with_null_and_two_types']; + } + + /** + * Sets property_with_null_and_two_types + * + * @param \OpenAPI\Client\Model\ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes|null $property_with_null_and_two_types property_with_null_and_two_types + * + * @return self + */ + public function setPropertyWithNullAndTwoTypes($property_with_null_and_two_types) + { + + if (is_null($property_with_null_and_two_types)) { + throw new \InvalidArgumentException('non-nullable property_with_null_and_two_types cannot be null'); + } + + $this->container['property_with_null_and_two_types'] = $property_with_null_and_two_types; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/samples/client/petstore/php/nullable-object-property-php/lib/Model/ModelWithNullableObjectPropertyNonNullableProperty.php b/samples/client/petstore/php/nullable-object-property-php/lib/Model/ModelWithNullableObjectPropertyNonNullableProperty.php new file mode 100644 index 000000000000..3cf6e523346b --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/lib/Model/ModelWithNullableObjectPropertyNonNullableProperty.php @@ -0,0 +1,371 @@ + + */ +class ModelWithNullableObjectPropertyNonNullableProperty implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'ModelWithNullableObjectProperty_nonNullableProperty'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[] $data Associated array of property values + * initializing the model + */ + public function __construct(array $data = null) + { + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/samples/client/petstore/php/nullable-object-property-php/lib/Model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.php b/samples/client/petstore/php/nullable-object-property-php/lib/Model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.php new file mode 100644 index 000000000000..9c38bcefeccb --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/lib/Model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.php @@ -0,0 +1,437 @@ + + */ +class ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'ModelWithNullableObjectProperty_propertyWithNullAndTwoTypes'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'foo' => 'string', + 'bar' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'foo' => null, + 'bar' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'foo' => false, + 'bar' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'foo' => 'foo', + 'bar' => 'bar' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'foo' => 'setFoo', + 'bar' => 'setBar' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'foo' => 'getFoo', + 'bar' => 'getBar' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[] $data Associated array of property values + * initializing the model + */ + public function __construct(array $data = null) + { + $this->setIfExists('foo', $data ?? [], null); + $this->setIfExists('bar', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets foo + * + * @return string|null + */ + public function getFoo() + { + return $this->container['foo']; + } + + /** + * Sets foo + * + * @param string|null $foo foo + * + * @return self + */ + public function setFoo($foo) + { + + if (is_null($foo)) { + throw new \InvalidArgumentException('non-nullable foo cannot be null'); + } + + $this->container['foo'] = $foo; + + return $this; + } + + /** + * Gets bar + * + * @return string|null + */ + public function getBar() + { + return $this->container['bar']; + } + + /** + * Sets bar + * + * @param string|null $bar bar + * + * @return self + */ + public function setBar($bar) + { + + if (is_null($bar)) { + throw new \InvalidArgumentException('non-nullable bar cannot be null'); + } + + $this->container['bar'] = $bar; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/samples/client/petstore/php/nullable-object-property-php/lib/Model/OtherPropertyType.php b/samples/client/petstore/php/nullable-object-property-php/lib/Model/OtherPropertyType.php new file mode 100644 index 000000000000..259140289df4 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/lib/Model/OtherPropertyType.php @@ -0,0 +1,401 @@ + + */ +class OtherPropertyType implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'OtherPropertyType'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'bar' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'bar' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'bar' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'bar' => 'bar' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'bar' => 'setBar' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'bar' => 'getBar' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[] $data Associated array of property values + * initializing the model + */ + public function __construct(array $data = null) + { + $this->setIfExists('bar', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets bar + * + * @return string|null + */ + public function getBar() + { + return $this->container['bar']; + } + + /** + * Sets bar + * + * @param string|null $bar bar + * + * @return self + */ + public function setBar($bar) + { + + if (is_null($bar)) { + throw new \InvalidArgumentException('non-nullable bar cannot be null'); + } + + $this->container['bar'] = $bar; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/samples/client/petstore/php/nullable-object-property-php/lib/Model/PropertyType.php b/samples/client/petstore/php/nullable-object-property-php/lib/Model/PropertyType.php new file mode 100644 index 000000000000..e165fe86c3ef --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/lib/Model/PropertyType.php @@ -0,0 +1,401 @@ + + */ +class PropertyType implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'PropertyType'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'foo' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'foo' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'foo' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'foo' => 'foo' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'foo' => 'setFoo' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'foo' => 'getFoo' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[] $data Associated array of property values + * initializing the model + */ + public function __construct(array $data = null) + { + $this->setIfExists('foo', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets foo + * + * @return string|null + */ + public function getFoo() + { + return $this->container['foo']; + } + + /** + * Sets foo + * + * @param string|null $foo foo + * + * @return self + */ + public function setFoo($foo) + { + + if (is_null($foo)) { + throw new \InvalidArgumentException('non-nullable foo cannot be null'); + } + + $this->container['foo'] = $foo; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/samples/client/petstore/php/nullable-object-property-php/lib/ObjectSerializer.php b/samples/client/petstore/php/nullable-object-property-php/lib/ObjectSerializer.php new file mode 100644 index 000000000000..9a30176ed091 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/lib/ObjectSerializer.php @@ -0,0 +1,517 @@ +format('Y-m-d') : $data->format(self::$dateTimeFormat); + } + + if (is_array($data)) { + foreach ($data as $property => $value) { + $data[$property] = self::sanitizeForSerialization($value); + } + return $data; + } + + if (is_object($data)) { + $values = []; + if ($data instanceof ModelInterface) { + $formats = $data::openAPIFormats(); + foreach ($data::openAPITypes() as $property => $openAPIType) { + $getter = $data::getters()[$property]; + $value = $data->$getter(); + if ($value !== null && !in_array($openAPIType, ['\DateTime', '\SplFileObject', 'array', 'bool', 'boolean', 'byte', 'double', 'float', 'int', 'integer', 'mixed', 'number', 'object', 'string', 'void'], true)) { + $callable = [$openAPIType, 'getAllowableEnumValues']; + if (is_callable($callable)) { + /** array $callable */ + $allowedEnumTypes = $callable(); + if (!in_array($value, $allowedEnumTypes, true)) { + $imploded = implode("', '", $allowedEnumTypes); + throw new \InvalidArgumentException("Invalid value for enum '$openAPIType', must be one of: '$imploded'"); + } + } + } + if (($data::isNullable($property) && $data->isNullableSetToNull($property)) || $value !== null) { + $values[$data::attributeMap()[$property]] = self::sanitizeForSerialization($value, $openAPIType, $formats[$property]); + } + } + } else { + foreach($data as $property => $value) { + $values[$property] = self::sanitizeForSerialization($value); + } + } + return (object)$values; + } else { + return (string)$data; + } + } + + /** + * Sanitize filename by removing path. + * e.g. ../../sun.gif becomes sun.gif + * + * @param string $filename filename to be sanitized + * + * @return string the sanitized filename + */ + public static function sanitizeFilename($filename) + { + if (preg_match("/.*[\/\\\\](.*)$/", $filename, $match)) { + return $match[1]; + } else { + return $filename; + } + } + + /** + * Shorter timestamp microseconds to 6 digits length. + * + * @param string $timestamp Original timestamp + * + * @return string the shorten timestamp + */ + public static function sanitizeTimestamp($timestamp) + { + if (!is_string($timestamp)) return $timestamp; + + return preg_replace('/(:\d{2}.\d{6})\d*/', '$1', $timestamp); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the path, by url-encoding. + * + * @param string $value a string which will be part of the path + * + * @return string the serialized object + */ + public static function toPathValue($value) + { + return rawurlencode(self::toString($value)); + } + + /** + * Take query parameter properties and turn it into an array suitable for + * native http_build_query or GuzzleHttp\Psr7\Query::build. + * + * @param mixed $value Parameter value + * @param string $paramName Parameter name + * @param string $openApiType OpenAPIType eg. array or object + * @param string $style Parameter serialization style + * @param bool $explode Parameter explode option + * @param bool $required Whether query param is required or not + * + * @return array + */ + public static function toQueryValue( + $value, + string $paramName, + string $openApiType = 'string', + string $style = 'form', + bool $explode = true, + bool $required = true + ): array { + if ( + empty($value) + && ($value !== false || $openApiType !== 'boolean') // if $value === false and $openApiType ==='boolean' it isn't empty + ) { + if ($required) { + return ["{$paramName}" => '']; + } else { + return []; + } + } + + $query = []; + $value = (in_array($openApiType, ['object', 'array'], true)) ? (array)$value : $value; + + // since \GuzzleHttp\Psr7\Query::build fails with nested arrays + // need to flatten array first + $flattenArray = function ($arr, $name, &$result = []) use (&$flattenArray, $style, $explode) { + if (!is_array($arr)) return $arr; + + foreach ($arr as $k => $v) { + $prop = ($style === 'deepObject') ? $prop = "{$name}[{$k}]" : $k; + + if (is_array($v)) { + $flattenArray($v, $prop, $result); + } else { + if ($style !== 'deepObject' && !$explode) { + // push key itself + $result[] = $prop; + } + $result[$prop] = $v; + } + } + return $result; + }; + + $value = $flattenArray($value, $paramName); + + if ($openApiType === 'object' && ($style === 'deepObject' || $explode)) { + return $value; + } + + if ('boolean' === $openApiType && is_bool($value)) { + $value = self::convertBoolToQueryStringFormat($value); + } + + // handle style in serializeCollection + $query[$paramName] = ($explode) ? $value : self::serializeCollection((array)$value, $style); + + return $query; + } + + /** + * Convert boolean value to format for query string. + * + * @param bool $value Boolean value + * + * @return int|string Boolean value in format + */ + public static function convertBoolToQueryStringFormat(bool $value) + { + if (Configuration::BOOLEAN_FORMAT_STRING == Configuration::getDefaultConfiguration()->getBooleanFormatForQueryString()) { + return $value ? 'true' : 'false'; + } + + return (int) $value; + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the header. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * + * @param string $value a string which will be part of the header + * + * @return string the header string + */ + public static function toHeaderValue($value) + { + $callable = [$value, 'toHeaderValue']; + if (is_callable($callable)) { + return $callable(); + } + + return self::toString($value); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the http body (form parameter). If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * + * @param string|\SplFileObject $value the value of the form parameter + * + * @return string the form string + */ + public static function toFormValue($value) + { + if ($value instanceof \SplFileObject) { + return $value->getRealPath(); + } else { + return self::toString($value); + } + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the parameter. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * If it's a boolean, convert it to "true" or "false". + * + * @param string|bool|\DateTime $value the value of the parameter + * + * @return string the header string + */ + public static function toString($value) + { + if ($value instanceof \DateTime) { // datetime in ISO8601 format + return $value->format(self::$dateTimeFormat); + } elseif (is_bool($value)) { + return $value ? 'true' : 'false'; + } else { + return (string) $value; + } + } + + /** + * Serialize an array to a string. + * + * @param array $collection collection to serialize to a string + * @param string $style the format use for serialization (csv, + * ssv, tsv, pipes, multi) + * @param bool $allowCollectionFormatMulti allow collection format to be a multidimensional array + * + * @return string + */ + public static function serializeCollection(array $collection, $style, $allowCollectionFormatMulti = false) + { + if ($allowCollectionFormatMulti && ('multi' === $style)) { + // http_build_query() almost does the job for us. We just + // need to fix the result of multidimensional arrays. + return preg_replace('/%5B[0-9]+%5D=/', '=', http_build_query($collection, '', '&')); + } + switch ($style) { + case 'pipeDelimited': + case 'pipes': + return implode('|', $collection); + + case 'tsv': + return implode("\t", $collection); + + case 'spaceDelimited': + case 'ssv': + return implode(' ', $collection); + + case 'simple': + case 'csv': + // Deliberate fall through. CSV is default format. + default: + return implode(',', $collection); + } + } + + /** + * Deserialize a JSON string into an object + * + * @param mixed $data object or primitive to be deserialized + * @param string $class class name is passed as a string + * @param string[] $httpHeaders HTTP headers + * @param string $discriminator discriminator if polymorphism is used + * + * @return object|array|null a single or an array of $class instances + */ + public static function deserialize($data, $class, $httpHeaders = null) + { + if (null === $data) { + return null; + } + + if (strcasecmp(substr($class, -2), '[]') === 0) { + $data = is_string($data) ? json_decode($data) : $data; + + if (!is_array($data)) { + throw new \InvalidArgumentException("Invalid array '$class'"); + } + + $subClass = substr($class, 0, -2); + $values = []; + foreach ($data as $key => $value) { + $values[] = self::deserialize($value, $subClass, null); + } + return $values; + } + + if (preg_match('/^(array<|map\[)/', $class)) { // for associative array e.g. array + $data = is_string($data) ? json_decode($data) : $data; + settype($data, 'array'); + $inner = substr($class, 4, -1); + $deserialized = []; + if (strrpos($inner, ",") !== false) { + $subClass_array = explode(',', $inner, 2); + $subClass = $subClass_array[1]; + foreach ($data as $key => $value) { + $deserialized[$key] = self::deserialize($value, $subClass, null); + } + } + return $deserialized; + } + + if ($class === 'object') { + settype($data, 'array'); + return $data; + } elseif ($class === 'mixed') { + settype($data, gettype($data)); + return $data; + } + + if ($class === '\DateTime') { + // Some API's return an invalid, empty string as a + // date-time property. DateTime::__construct() will return + // the current time for empty input which is probably not + // what is meant. The invalid empty string is probably to + // be interpreted as a missing field/value. Let's handle + // this graceful. + if (!empty($data)) { + try { + return new \DateTime($data); + } catch (\Exception $exception) { + // Some API's return a date-time with too high nanosecond + // precision for php's DateTime to handle. + // With provided regexp 6 digits of microseconds saved + return new \DateTime(self::sanitizeTimestamp($data)); + } + } else { + return null; + } + } + + if ($class === '\SplFileObject') { + $data = Utils::streamFor($data); + + /** @var \Psr\Http\Message\StreamInterface $data */ + + // determine file name + if ( + is_array($httpHeaders) + && array_key_exists('Content-Disposition', $httpHeaders) + && preg_match('/inline; filename=[\'"]?([^\'"\s]+)[\'"]?$/i', $httpHeaders['Content-Disposition'], $match) + ) { + $filename = Configuration::getDefaultConfiguration()->getTempFolderPath() . DIRECTORY_SEPARATOR . self::sanitizeFilename($match[1]); + } else { + $filename = tempnam(Configuration::getDefaultConfiguration()->getTempFolderPath(), ''); + } + + $file = fopen($filename, 'w'); + while ($chunk = $data->read(200)) { + fwrite($file, $chunk); + } + fclose($file); + + return new \SplFileObject($filename, 'r'); + } + + /** @psalm-suppress ParadoxicalCondition */ + if (in_array($class, ['\DateTime', '\SplFileObject', 'array', 'bool', 'boolean', 'byte', 'double', 'float', 'int', 'integer', 'mixed', 'number', 'object', 'string', 'void'], true)) { + settype($data, $class); + return $data; + } + + + if (method_exists($class, 'getAllowableEnumValues')) { + if (!in_array($data, $class::getAllowableEnumValues(), true)) { + $imploded = implode("', '", $class::getAllowableEnumValues()); + throw new \InvalidArgumentException("Invalid value for enum '$class', must be one of: '$imploded'"); + } + return $data; + } else { + $data = is_string($data) ? json_decode($data) : $data; + + if (is_array($data)) { + $data = (object)$data; + } + + // If a discriminator is defined and points to a valid subclass, use it. + $discriminator = $class::DISCRIMINATOR; + if (!empty($discriminator) && isset($data->{$discriminator}) && is_string($data->{$discriminator})) { + $subclass = '\OpenAPI\Client\Model\\' . $data->{$discriminator}; + if (is_subclass_of($subclass, $class)) { + $class = $subclass; + } + } + + /** @var ModelInterface $instance */ + $instance = new $class(); + foreach ($instance::openAPITypes() as $property => $type) { + $propertySetter = $instance::setters()[$property]; + + if (!isset($propertySetter)) { + continue; + } + + if (!isset($data->{$instance::attributeMap()[$property]})) { + if ($instance::isNullable($property)) { + $instance->$propertySetter(null); + } + + continue; + } + + if (isset($data->{$instance::attributeMap()[$property]})) { + $propertyValue = $data->{$instance::attributeMap()[$property]}; + $instance->$propertySetter(self::deserialize($propertyValue, $type, null)); + } + } + return $instance; + } + } + + /** + * Native `http_build_query` wrapper. + * @see https://www.php.net/manual/en/function.http-build-query + * + * @param array|object $data May be an array or object containing properties. + * @param string $numeric_prefix If numeric indices are used in the base array and this parameter is provided, it will be prepended to the numeric index for elements in the base array only. + * @param string|null $arg_separator arg_separator.output is used to separate arguments but may be overridden by specifying this parameter. + * @param int $encoding_type Encoding type. By default, PHP_QUERY_RFC1738. + * + * @return string + */ + public static function buildQuery( + $data, + string $numeric_prefix = '', + ?string $arg_separator = null, + int $encoding_type = \PHP_QUERY_RFC3986 + ): string { + return \GuzzleHttp\Psr7\Query::build($data, $encoding_type); + } +} diff --git a/samples/client/petstore/php/nullable-object-property-php/phpunit.xml.dist b/samples/client/petstore/php/nullable-object-property-php/phpunit.xml.dist new file mode 100644 index 000000000000..485899aaf215 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/phpunit.xml.dist @@ -0,0 +1,18 @@ + + + + + ./lib/Api + ./lib/Model + + + + + ./test/Api + ./test/Model + + + + + + diff --git a/samples/client/petstore/php/nullable-object-property-php/test/Api/DefaultApiTest.php b/samples/client/petstore/php/nullable-object-property-php/test/Api/DefaultApiTest.php new file mode 100644 index 000000000000..b51743232bd1 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/test/Api/DefaultApiTest.php @@ -0,0 +1,85 @@ +markTestIncomplete('Not implemented'); + } +} diff --git a/samples/client/petstore/php/nullable-object-property-php/test/Model/ModelWithNullableObjectPropertyNonNullablePropertyTest.php b/samples/client/petstore/php/nullable-object-property-php/test/Model/ModelWithNullableObjectPropertyNonNullablePropertyTest.php new file mode 100644 index 000000000000..25325d324253 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/test/Model/ModelWithNullableObjectPropertyNonNullablePropertyTest.php @@ -0,0 +1,81 @@ +markTestIncomplete('Not implemented'); + } +} diff --git a/samples/client/petstore/php/nullable-object-property-php/test/Model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesTest.php b/samples/client/petstore/php/nullable-object-property-php/test/Model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesTest.php new file mode 100644 index 000000000000..72a390202c95 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/test/Model/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesTest.php @@ -0,0 +1,99 @@ +markTestIncomplete('Not implemented'); + } + + /** + * Test attribute "foo" + */ + public function testPropertyFoo() + { + // TODO: implement + $this->markTestIncomplete('Not implemented'); + } + + /** + * Test attribute "bar" + */ + public function testPropertyBar() + { + // TODO: implement + $this->markTestIncomplete('Not implemented'); + } +} diff --git a/samples/client/petstore/php/nullable-object-property-php/test/Model/ModelWithNullableObjectPropertyTest.php b/samples/client/petstore/php/nullable-object-property-php/test/Model/ModelWithNullableObjectPropertyTest.php new file mode 100644 index 000000000000..f45f3b01fa4c --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/test/Model/ModelWithNullableObjectPropertyTest.php @@ -0,0 +1,126 @@ +markTestIncomplete('Not implemented'); + } + + /** + * Test attribute "property_name" + */ + public function testPropertyPropertyName() + { + // TODO: implement + $this->markTestIncomplete('Not implemented'); + } + + /** + * Test attribute "property_name30" + */ + public function testPropertyPropertyName30() + { + // TODO: implement + $this->markTestIncomplete('Not implemented'); + } + + /** + * Test attribute "property_name31" + */ + public function testPropertyPropertyName31() + { + // TODO: implement + $this->markTestIncomplete('Not implemented'); + } + + /** + * Test attribute "non_nullable_property" + */ + public function testPropertyNonNullableProperty() + { + // TODO: implement + $this->markTestIncomplete('Not implemented'); + } + + /** + * Test attribute "property_with_null_and_two_types" + */ + public function testPropertyPropertyWithNullAndTwoTypes() + { + // TODO: implement + $this->markTestIncomplete('Not implemented'); + } +} diff --git a/samples/client/petstore/php/nullable-object-property-php/test/Model/OtherPropertyTypeTest.php b/samples/client/petstore/php/nullable-object-property-php/test/Model/OtherPropertyTypeTest.php new file mode 100644 index 000000000000..cb37c26fafc9 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/test/Model/OtherPropertyTypeTest.php @@ -0,0 +1,90 @@ +markTestIncomplete('Not implemented'); + } + + /** + * Test attribute "bar" + */ + public function testPropertyBar() + { + // TODO: implement + $this->markTestIncomplete('Not implemented'); + } +} diff --git a/samples/client/petstore/php/nullable-object-property-php/test/Model/PropertyTypeTest.php b/samples/client/petstore/php/nullable-object-property-php/test/Model/PropertyTypeTest.php new file mode 100644 index 000000000000..eaf3c38d6d00 --- /dev/null +++ b/samples/client/petstore/php/nullable-object-property-php/test/Model/PropertyTypeTest.php @@ -0,0 +1,90 @@ +markTestIncomplete('Not implemented'); + } + + /** + * Test attribute "foo" + */ + public function testPropertyFoo() + { + // TODO: implement + $this->markTestIncomplete('Not implemented'); + } +} diff --git a/samples/client/petstore/typescript-axios/builds/test-petstore/api.ts b/samples/client/petstore/typescript-axios/builds/test-petstore/api.ts index 1400ca368613..1ad3a6f8374a 100644 --- a/samples/client/petstore/typescript-axios/builds/test-petstore/api.ts +++ b/samples/client/petstore/typescript-axios/builds/test-petstore/api.ts @@ -844,7 +844,7 @@ export type Fruit = Apple | Banana; * @type FruitReq * @export */ -export type FruitReq = AppleReq | BananaReq | Null; +export type FruitReq = AppleReq | BananaReq | null; /** * @@ -1518,7 +1518,7 @@ export interface ShapeInterface { * The value may be a shape or the \'null\' value. This is introduced in OAS schema >= 3.1. * @export */ -export type ShapeOrNull = Null | Quadrilateral | Triangle; +export type ShapeOrNull = Quadrilateral | Triangle | null; /** * diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/.openapi-generator-ignore b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/.openapi-generator/FILES b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/.openapi-generator/FILES new file mode 100644 index 000000000000..f8140acc6af7 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/.openapi-generator/FILES @@ -0,0 +1,10 @@ +apis/DefaultApi.ts +apis/index.ts +index.ts +models/ModelWithNullableObjectProperty.ts +models/ModelWithNullableObjectPropertyNonNullableProperty.ts +models/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.ts +models/OtherPropertyType.ts +models/PropertyType.ts +models/index.ts +runtime.ts diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/.openapi-generator/VERSION b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/.openapi-generator/VERSION new file mode 100644 index 000000000000..66672d4e9d31 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/.openapi-generator/VERSION @@ -0,0 +1 @@ +6.1.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/apis/DefaultApi.ts b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/apis/DefaultApi.ts new file mode 100644 index 000000000000..cb9467280e4e --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/apis/DefaultApi.ts @@ -0,0 +1,54 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + ModelWithNullableObjectProperty, +} from '../models'; +import { + ModelWithNullableObjectPropertyFromJSON, + ModelWithNullableObjectPropertyToJSON, +} from '../models'; + +/** + * + */ +export class DefaultApi extends runtime.BaseAPI { + + /** + */ + async operationRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ModelWithNullableObjectPropertyFromJSON(jsonValue)); + } + + /** + */ + async operation(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.operationRaw(initOverrides); + return await response.value(); + } + +} diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/apis/index.ts b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/apis/index.ts new file mode 100644 index 000000000000..69c44c00fa0d --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/apis/index.ts @@ -0,0 +1,3 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './DefaultApi'; diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/index.ts b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/index.ts new file mode 100644 index 000000000000..be9d1edeefeb --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/index.ts @@ -0,0 +1,5 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './runtime'; +export * from './apis'; +export * from './models'; diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/ModelWithNullableObjectProperty.ts b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/ModelWithNullableObjectProperty.ts new file mode 100644 index 000000000000..60bb0a7815d4 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/ModelWithNullableObjectProperty.ts @@ -0,0 +1,116 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { ModelWithNullableObjectPropertyNonNullableProperty } from './ModelWithNullableObjectPropertyNonNullableProperty'; +import { + ModelWithNullableObjectPropertyNonNullablePropertyFromJSON, + ModelWithNullableObjectPropertyNonNullablePropertyFromJSONTyped, + ModelWithNullableObjectPropertyNonNullablePropertyToJSON, +} from './ModelWithNullableObjectPropertyNonNullableProperty'; +import type { ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes } from './ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes'; +import { + ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesFromJSON, + ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesFromJSONTyped, + ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesToJSON, +} from './ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes'; +import type { PropertyType } from './PropertyType'; +import { + PropertyTypeFromJSON, + PropertyTypeFromJSONTyped, + PropertyTypeToJSON, +} from './PropertyType'; + +/** + * + * @export + * @interface ModelWithNullableObjectProperty + */ +export interface ModelWithNullableObjectProperty { + /** + * + * @type {PropertyType} + * @memberof ModelWithNullableObjectProperty + */ + propertyName?: PropertyType; + /** + * + * @type {PropertyType} + * @memberof ModelWithNullableObjectProperty + */ + propertyName30?: PropertyType | null; + /** + * + * @type {PropertyType} + * @memberof ModelWithNullableObjectProperty + */ + propertyName31?: PropertyType | null; + /** + * + * @type {ModelWithNullableObjectPropertyNonNullableProperty} + * @memberof ModelWithNullableObjectProperty + */ + nonNullableProperty?: ModelWithNullableObjectPropertyNonNullableProperty; + /** + * + * @type {ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes} + * @memberof ModelWithNullableObjectProperty + */ + propertyWithNullAndTwoTypes?: ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes; +} + +/** + * Check if a given object implements the ModelWithNullableObjectProperty interface. + */ +export function instanceOfModelWithNullableObjectProperty(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function ModelWithNullableObjectPropertyFromJSON(json: any): ModelWithNullableObjectProperty { + return ModelWithNullableObjectPropertyFromJSONTyped(json, false); +} + +export function ModelWithNullableObjectPropertyFromJSONTyped(json: any, ignoreDiscriminator: boolean): ModelWithNullableObjectProperty { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'propertyName': !exists(json, 'propertyName') ? undefined : PropertyTypeFromJSON(json['propertyName']), + 'propertyName30': !exists(json, 'propertyName30') ? undefined : PropertyTypeFromJSON(json['propertyName30']), + 'propertyName31': !exists(json, 'propertyName31') ? undefined : PropertyTypeFromJSON(json['propertyName31']), + 'nonNullableProperty': !exists(json, 'nonNullableProperty') ? undefined : ModelWithNullableObjectPropertyNonNullablePropertyFromJSON(json['nonNullableProperty']), + 'propertyWithNullAndTwoTypes': !exists(json, 'propertyWithNullAndTwoTypes') ? undefined : ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesFromJSON(json['propertyWithNullAndTwoTypes']), + }; +} + +export function ModelWithNullableObjectPropertyToJSON(value?: ModelWithNullableObjectProperty | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'propertyName': PropertyTypeToJSON(value.propertyName), + 'propertyName30': PropertyTypeToJSON(value.propertyName30), + 'propertyName31': PropertyTypeToJSON(value.propertyName31), + 'nonNullableProperty': ModelWithNullableObjectPropertyNonNullablePropertyToJSON(value.nonNullableProperty), + 'propertyWithNullAndTwoTypes': ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesToJSON(value.propertyWithNullAndTwoTypes), + }; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/ModelWithNullableObjectPropertyNonNullableProperty.ts b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/ModelWithNullableObjectPropertyNonNullableProperty.ts new file mode 100644 index 000000000000..7ce073a9f4b1 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/ModelWithNullableObjectPropertyNonNullableProperty.ts @@ -0,0 +1,50 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +/** + * @type ModelWithNullableObjectPropertyNonNullableProperty + * + * @export + */ +export type ModelWithNullableObjectPropertyNonNullableProperty = number | string; + +export function ModelWithNullableObjectPropertyNonNullablePropertyFromJSON(json: any): ModelWithNullableObjectPropertyNonNullableProperty { + return ModelWithNullableObjectPropertyNonNullablePropertyFromJSONTyped(json, false); +} + +export function ModelWithNullableObjectPropertyNonNullablePropertyFromJSONTyped(json: any, ignoreDiscriminator: boolean): ModelWithNullableObjectPropertyNonNullableProperty { + if ((json === undefined) || (json === null)) { + return json; + } + return { ...numberFromJSONTyped(json, true), ...stringFromJSONTyped(json, true) }; +} + +export function ModelWithNullableObjectPropertyNonNullablePropertyToJSON(value?: ModelWithNullableObjectPropertyNonNullableProperty | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + + if (instanceOfnumber(value)) { + return numberToJSON(value as number); + } + if (instanceOfstring(value)) { + return stringToJSON(value as string); + } + + return {}; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.ts b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.ts new file mode 100644 index 000000000000..5cb9facadeec --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { + OtherPropertyType, + instanceOfOtherPropertyType, + OtherPropertyTypeFromJSON, + OtherPropertyTypeFromJSONTyped, + OtherPropertyTypeToJSON, +} from './OtherPropertyType'; +import { + PropertyType, + instanceOfPropertyType, + PropertyTypeFromJSON, + PropertyTypeFromJSONTyped, + PropertyTypeToJSON, +} from './PropertyType'; +import { + null, + instanceOfnull, + nullFromJSON, + nullFromJSONTyped, + nullToJSON, +} from './null'; + +/** + * @type ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes + * + * @export + */ +export type ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes = OtherPropertyType | PropertyType | null; + +export function ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesFromJSON(json: any): ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes { + return ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesFromJSONTyped(json, false); +} + +export function ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesFromJSONTyped(json: any, ignoreDiscriminator: boolean): ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes { + if ((json === undefined) || (json === null)) { + return json; + } + return { ...OtherPropertyTypeFromJSONTyped(json, true), ...PropertyTypeFromJSONTyped(json, true), ...nullFromJSONTyped(json, true) }; +} + +export function ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypesToJSON(value?: ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + + if (instanceOfOtherPropertyType(value)) { + return OtherPropertyTypeToJSON(value as OtherPropertyType); + } + if (instanceOfPropertyType(value)) { + return PropertyTypeToJSON(value as PropertyType); + } + if (instanceOfnull(value)) { + return nullToJSON(value as null); + } + + return {}; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/OtherPropertyType.ts b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/OtherPropertyType.ts new file mode 100644 index 000000000000..758aa3f5d1a9 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/OtherPropertyType.ts @@ -0,0 +1,65 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface OtherPropertyType + */ +export interface OtherPropertyType { + /** + * + * @type {string} + * @memberof OtherPropertyType + */ + bar?: string; +} + +/** + * Check if a given object implements the OtherPropertyType interface. + */ +export function instanceOfOtherPropertyType(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function OtherPropertyTypeFromJSON(json: any): OtherPropertyType { + return OtherPropertyTypeFromJSONTyped(json, false); +} + +export function OtherPropertyTypeFromJSONTyped(json: any, ignoreDiscriminator: boolean): OtherPropertyType { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'bar': !exists(json, 'bar') ? undefined : json['bar'], + }; +} + +export function OtherPropertyTypeToJSON(value?: OtherPropertyType | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'bar': value.bar, + }; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/PropertyType.ts b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/PropertyType.ts new file mode 100644 index 000000000000..6b8af378205d --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/PropertyType.ts @@ -0,0 +1,65 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface PropertyType + */ +export interface PropertyType { + /** + * + * @type {string} + * @memberof PropertyType + */ + foo?: string; +} + +/** + * Check if a given object implements the PropertyType interface. + */ +export function instanceOfPropertyType(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function PropertyTypeFromJSON(json: any): PropertyType { + return PropertyTypeFromJSONTyped(json, false); +} + +export function PropertyTypeFromJSONTyped(json: any, ignoreDiscriminator: boolean): PropertyType { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'foo': !exists(json, 'foo') ? undefined : json['foo'], + }; +} + +export function PropertyTypeToJSON(value?: PropertyType | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'foo': value.foo, + }; +} + diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/index.ts b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/index.ts new file mode 100644 index 000000000000..7b498efc7787 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/models/index.ts @@ -0,0 +1,7 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './ModelWithNullableObjectProperty'; +export * from './ModelWithNullableObjectPropertyNonNullableProperty'; +export * from './ModelWithNullableObjectPropertyPropertyWithNullAndTwoTypes'; +export * from './OtherPropertyType'; +export * from './PropertyType'; diff --git a/samples/client/petstore/typescript-fetch/builds/nullable-object-property/runtime.ts b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/runtime.ts new file mode 100644 index 000000000000..79c6f7ff07b6 --- /dev/null +++ b/samples/client/petstore/typescript-fetch/builds/nullable-object-property/runtime.ts @@ -0,0 +1,407 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Title + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export const BASE_PATH = "http://localhost".replace(/\/+$/, ""); + +export interface ConfigurationParameters { + basePath?: string; // override base path + fetchApi?: FetchAPI; // override for fetch implementation + middleware?: Middleware[]; // middleware to apply before/after fetch requests + queryParamsStringify?: (params: HTTPQuery) => string; // stringify function for query strings + username?: string; // parameter for basic security + password?: string; // parameter for basic security + apiKey?: string | ((name: string) => string); // parameter for apiKey security + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string | Promise); // parameter for oauth2 security + headers?: HTTPHeaders; //header params we want to use on every request + credentials?: RequestCredentials; //value for the credentials param we want to use on each request +} + +export class Configuration { + constructor(private configuration: ConfigurationParameters = {}) {} + + set config(configuration: Configuration) { + this.configuration = configuration; + } + + get basePath(): string { + return this.configuration.basePath != null ? this.configuration.basePath : BASE_PATH; + } + + get fetchApi(): FetchAPI | undefined { + return this.configuration.fetchApi; + } + + get middleware(): Middleware[] { + return this.configuration.middleware || []; + } + + get queryParamsStringify(): (params: HTTPQuery) => string { + return this.configuration.queryParamsStringify || querystring; + } + + get username(): string | undefined { + return this.configuration.username; + } + + get password(): string | undefined { + return this.configuration.password; + } + + get apiKey(): ((name: string) => string) | undefined { + const apiKey = this.configuration.apiKey; + if (apiKey) { + return typeof apiKey === 'function' ? apiKey : () => apiKey; + } + return undefined; + } + + get accessToken(): ((name?: string, scopes?: string[]) => string | Promise) | undefined { + const accessToken = this.configuration.accessToken; + if (accessToken) { + return typeof accessToken === 'function' ? accessToken : async () => accessToken; + } + return undefined; + } + + get headers(): HTTPHeaders | undefined { + return this.configuration.headers; + } + + get credentials(): RequestCredentials | undefined { + return this.configuration.credentials; + } +} + +export const DefaultConfig = new Configuration(); + +/** + * This is the base class for all generated API classes. + */ +export class BaseAPI { + + private middleware: Middleware[]; + + constructor(protected configuration = DefaultConfig) { + this.middleware = configuration.middleware; + } + + withMiddleware(this: T, ...middlewares: Middleware[]) { + const next = this.clone(); + next.middleware = next.middleware.concat(...middlewares); + return next; + } + + withPreMiddleware(this: T, ...preMiddlewares: Array) { + const middlewares = preMiddlewares.map((pre) => ({ pre })); + return this.withMiddleware(...middlewares); + } + + withPostMiddleware(this: T, ...postMiddlewares: Array) { + const middlewares = postMiddlewares.map((post) => ({ post })); + return this.withMiddleware(...middlewares); + } + + protected async request(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction): Promise { + const { url, init } = await this.createFetchParams(context, initOverrides); + const response = await this.fetchApi(url, init); + if (response.status >= 200 && response.status < 300) { + return response; + } + throw new ResponseError(response, 'Response returned an error code'); + } + + private async createFetchParams(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction) { + let url = this.configuration.basePath + context.path; + if (context.query !== undefined && Object.keys(context.query).length !== 0) { + // only add the querystring to the URL if there are query parameters. + // this is done to avoid urls ending with a "?" character which buggy webservers + // do not handle correctly sometimes. + url += '?' + this.configuration.queryParamsStringify(context.query); + } + + const headers = Object.assign({}, this.configuration.headers, context.headers); + Object.keys(headers).forEach(key => headers[key] === undefined ? delete headers[key] : {}); + + const initOverrideFn = + typeof initOverrides === "function" + ? initOverrides + : async () => initOverrides; + + const initParams = { + method: context.method, + headers, + body: context.body, + credentials: this.configuration.credentials, + }; + + const overridedInit: RequestInit = { + ...initParams, + ...(await initOverrideFn({ + init: initParams, + context, + })) + } + + const init: RequestInit = { + ...overridedInit, + body: + isFormData(overridedInit.body) || + overridedInit.body instanceof URLSearchParams || + isBlob(overridedInit.body) + ? overridedInit.body + : JSON.stringify(overridedInit.body), + }; + + return { url, init }; + } + + private fetchApi = async (url: string, init: RequestInit) => { + let fetchParams = { url, init }; + for (const middleware of this.middleware) { + if (middleware.pre) { + fetchParams = await middleware.pre({ + fetch: this.fetchApi, + ...fetchParams, + }) || fetchParams; + } + } + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response === undefined) { + if (e instanceof Error) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } else { + throw e; + } + } + } + for (const middleware of this.middleware) { + if (middleware.post) { + response = await middleware.post({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + response: response.clone(), + }) || response; + } + } + return response; + } + + /** + * Create a shallow clone of `this` by constructing a new instance + * and then shallow cloning data members. + */ + private clone(this: T): T { + const constructor = this.constructor as any; + const next = new constructor(this.configuration); + next.middleware = this.middleware.slice(); + return next; + } +}; + +function isBlob(value: any): value is Blob { + return typeof Blob !== 'undefined' && value instanceof Blob +} + +function isFormData(value: any): value is FormData { + return typeof FormData !== "undefined" && value instanceof FormData +} + +export class ResponseError extends Error { + name: "ResponseError" = "ResponseError"; + constructor(public response: Response, msg?: string) { + super(msg); + } +} + +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: Error, msg?: string) { + super(msg); + } +} + +export class RequiredError extends Error { + name: "RequiredError" = "RequiredError"; + constructor(public field: string, msg?: string) { + super(msg); + } +} + +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + +export type FetchAPI = WindowOrWorkerGlobalScope['fetch']; + +export type Json = any; +export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD'; +export type HTTPHeaders = { [key: string]: string }; +export type HTTPQuery = { [key: string]: string | number | null | boolean | Array | Set | HTTPQuery }; +export type HTTPBody = Json | FormData | URLSearchParams; +export type HTTPRequestInit = { headers?: HTTPHeaders; method: HTTPMethod; credentials?: RequestCredentials; body?: HTTPBody } +export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; + +export type InitOverrideFunction = (requestContext: { init: HTTPRequestInit, context: RequestOpts }) => Promise + +export interface FetchParams { + url: string; + init: RequestInit; +} + +export interface RequestOpts { + path: string; + method: HTTPMethod; + headers: HTTPHeaders; + query?: HTTPQuery; + body?: HTTPBody; +} + +export function exists(json: any, key: string) { + const value = json[key]; + return value !== null && value !== undefined; +} + +export function querystring(params: HTTPQuery, prefix: string = ''): string { + return Object.keys(params) + .map(key => querystringSingleKey(key, params[key], prefix)) + .filter(part => part.length > 0) + .join('&'); +} + +function querystringSingleKey(key: string, value: string | number | null | undefined | boolean | Array | Set | HTTPQuery, keyPrefix: string = ''): string { + const fullKey = keyPrefix + (keyPrefix.length ? `[${key}]` : key); + if (value instanceof Array) { + const multiValue = value.map(singleValue => encodeURIComponent(String(singleValue))) + .join(`&${encodeURIComponent(fullKey)}=`); + return `${encodeURIComponent(fullKey)}=${multiValue}`; + } + if (value instanceof Set) { + const valueAsArray = Array.from(value); + return querystringSingleKey(key, valueAsArray, keyPrefix); + } + if (value instanceof Date) { + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value.toISOString())}`; + } + if (value instanceof Object) { + return querystring(value as HTTPQuery, fullKey); + } + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`; +} + +export function mapValues(data: any, fn: (item: any) => any) { + return Object.keys(data).reduce( + (acc, key) => ({ ...acc, [key]: fn(data[key]) }), + {} + ); +} + +export function canConsumeForm(consumes: Consume[]): boolean { + for (const consume of consumes) { + if ('multipart/form-data' === consume.contentType) { + return true; + } + } + return false; +} + +export interface Consume { + contentType: string +} + +export interface RequestContext { + fetch: FetchAPI; + url: string; + init: RequestInit; +} + +export interface ResponseContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + response: Response; +} + +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + +export interface Middleware { + pre?(context: RequestContext): Promise; + post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; +} + +export interface ApiResponse { + raw: Response; + value(): Promise; +} + +export interface ResponseTransformer { + (json: any): T; +} + +export class JSONApiResponse { + constructor(public raw: Response, private transformer: ResponseTransformer = (jsonValue: any) => jsonValue) {} + + async value(): Promise { + return this.transformer(await this.raw.json()); + } +} + +export class VoidApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return undefined; + } +} + +export class BlobApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.blob(); + }; +} + +export class TextApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.text(); + }; +}