From 68bae4918e7bd9d17827abd671e02c14b6b7b9f7 Mon Sep 17 00:00:00 2001 From: Jasper van Gelder <7516555+jvgelder@users.noreply.github.com> Date: Mon, 5 Jun 2023 22:12:31 +0200 Subject: [PATCH] fix: References for for protobuf objects (#466) --- CHANGELOG.md | 2 + .../kompendium/json/schema/util/Helpers.kt | 2 +- .../converters/FieldDescriptiorConverters.kt | 5 +- .../FieldDescriptiorConvertersKtTest.kt | 78 +++++++++- .../T0001__simpletestmessage_post.json | 127 +++++++++++++++ .../resources/T0002__enummessage_post.json | 86 +++++++++++ .../T0003__repeatedmessage_post.json | 138 +++++++++++++++++ .../resources/T0004__nestedmessage_post.json | 135 ++++++++++++++++ .../T0005__nestedmapmessage_post.json | 146 ++++++++++++++++++ 9 files changed, 709 insertions(+), 10 deletions(-) create mode 100644 protobuf-java-converter/src/test/resources/T0001__simpletestmessage_post.json create mode 100644 protobuf-java-converter/src/test/resources/T0002__enummessage_post.json create mode 100644 protobuf-java-converter/src/test/resources/T0003__repeatedmessage_post.json create mode 100644 protobuf-java-converter/src/test/resources/T0004__nestedmessage_post.json create mode 100644 protobuf-java-converter/src/test/resources/T0005__nestedmapmessage_post.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 025a23eee..81d8fbf3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ ### Changed +- Components definitions were not in the proper schema section. Prefixed the path with component slug in `protobuf java converter`. + ### Remove --- diff --git a/json-schema/src/main/kotlin/io/bkbn/kompendium/json/schema/util/Helpers.kt b/json-schema/src/main/kotlin/io/bkbn/kompendium/json/schema/util/Helpers.kt index cac51befb..2bc61693e 100644 --- a/json-schema/src/main/kotlin/io/bkbn/kompendium/json/schema/util/Helpers.kt +++ b/json-schema/src/main/kotlin/io/bkbn/kompendium/json/schema/util/Helpers.kt @@ -8,7 +8,7 @@ import kotlin.reflect.KType object Helpers { - private const val COMPONENT_SLUG = "#/components/schemas" + const val COMPONENT_SLUG = "#/components/schemas" fun KType.getSlug(enrichment: Enrichment? = null) = when (enrichment) { is TypeEnrichment<*> -> getEnrichedSlug(enrichment) diff --git a/protobuf-java-converter/src/main/kotlin/io/bkbn/kompendium/protobufjavaconverter/converters/FieldDescriptiorConverters.kt b/protobuf-java-converter/src/main/kotlin/io/bkbn/kompendium/protobufjavaconverter/converters/FieldDescriptiorConverters.kt index 3c35ca164..970081801 100644 --- a/protobuf-java-converter/src/main/kotlin/io/bkbn/kompendium/protobufjavaconverter/converters/FieldDescriptiorConverters.kt +++ b/protobuf-java-converter/src/main/kotlin/io/bkbn/kompendium/protobufjavaconverter/converters/FieldDescriptiorConverters.kt @@ -9,6 +9,7 @@ import io.bkbn.kompendium.json.schema.definition.MapDefinition import io.bkbn.kompendium.json.schema.definition.NullableDefinition import io.bkbn.kompendium.json.schema.definition.ReferenceDefinition import io.bkbn.kompendium.json.schema.definition.TypeDefinition +import io.bkbn.kompendium.json.schema.util.Helpers import kotlin.reflect.KType import kotlin.reflect.full.createType @@ -150,7 +151,7 @@ fun fromTypeToSchema( type = "string", enum = javaProtoField.enumType.values.map { it.name }.toSet() ) - ReferenceDefinition(javaProtoField.enumType.name) + ReferenceDefinition("${Helpers.COMPONENT_SLUG}/${javaProtoField.enumType.name}") } Descriptors.FieldDescriptor.JavaType.MESSAGE -> { // Traverse through possible nested messages @@ -160,7 +161,7 @@ fun fromTypeToSchema( it.jsonName to fromNestedTypeToSchema(it, cache) }.toMap() ) - ReferenceDefinition(javaProtoField.messageType.name) + ReferenceDefinition("${Helpers.COMPONENT_SLUG}/${javaProtoField.messageType.name}") } null -> NullableDefinition() } diff --git a/protobuf-java-converter/src/test/kotlin/io/bkbn/kompendium/protobufjavaconverter/converters/FieldDescriptiorConvertersKtTest.kt b/protobuf-java-converter/src/test/kotlin/io/bkbn/kompendium/protobufjavaconverter/converters/FieldDescriptiorConvertersKtTest.kt index cfce8e748..4e5cea04f 100644 --- a/protobuf-java-converter/src/test/kotlin/io/bkbn/kompendium/protobufjavaconverter/converters/FieldDescriptiorConvertersKtTest.kt +++ b/protobuf-java-converter/src/test/kotlin/io/bkbn/kompendium/protobufjavaconverter/converters/FieldDescriptiorConvertersKtTest.kt @@ -2,17 +2,21 @@ package io.bkbn.kompendium.protobufjavaconverter.converters import com.google.protobuf.Descriptors import com.google.protobuf.GeneratedMessageV3 +import io.bkbn.kompendium.core.fixtures.TestHelpers.openApiTestAllSerializers +import io.bkbn.kompendium.core.metadata.PostInfo +import io.bkbn.kompendium.core.plugin.NotarizedRoute import io.bkbn.kompendium.json.schema.definition.ArrayDefinition import io.bkbn.kompendium.json.schema.definition.EnumDefinition import io.bkbn.kompendium.json.schema.definition.JsonSchema import io.bkbn.kompendium.json.schema.definition.MapDefinition import io.bkbn.kompendium.json.schema.definition.ReferenceDefinition import io.bkbn.kompendium.json.schema.definition.TypeDefinition +import io.bkbn.kompendium.json.schema.util.Helpers import io.bkbn.kompendium.protobufjavaconverter.Corpus import io.bkbn.kompendium.protobufjavaconverter.DoubleNestedMessage -import io.bkbn.kompendium.protobufjavaconverter.NestedMapMessage import io.bkbn.kompendium.protobufjavaconverter.EnumMessage import io.bkbn.kompendium.protobufjavaconverter.GoogleTypes +import io.bkbn.kompendium.protobufjavaconverter.NestedMapMessage import io.bkbn.kompendium.protobufjavaconverter.NestedMessage import io.bkbn.kompendium.protobufjavaconverter.RepeatedEnumMessage import io.bkbn.kompendium.protobufjavaconverter.RepeatedMessage @@ -23,10 +27,15 @@ import io.kotest.matchers.maps.shouldContainExactly import io.kotest.matchers.shouldBe import io.kotest.matchers.types.shouldBeTypeOf import io.kotest.matchers.types.shouldNotBeTypeOf +import io.ktor.http.HttpStatusCode +import io.ktor.server.application.install +import io.ktor.server.routing.Route import kotlin.reflect.KType import kotlin.reflect.full.createType class FieldDescriptiorConvertersKtTest : DescribeSpec({ + + val componentSlug = Helpers.COMPONENT_SLUG describe("fromTypeToSchemaTests") { val simpleMessageDescriptor = SimpleTestMessage.getDescriptor() it("java int field should return TypeDefinition INT") { @@ -77,7 +86,7 @@ class FieldDescriptiorConvertersKtTest : DescribeSpec({ val message = NestedMessage.getDescriptor() val result = fromNestedTypeToSchema(message.findFieldByName("nested_field")) result.shouldBeTypeOf() - result.`$ref`.shouldBe(message.findFieldByName("nested_field").messageType.name) + result.`$ref`.shouldBe("${Helpers.COMPONENT_SLUG}/${message.findFieldByName("nested_field").messageType.name}") } it("Repeated message should return ArrayDefinition") { @@ -85,7 +94,7 @@ class FieldDescriptiorConvertersKtTest : DescribeSpec({ val result = fromNestedTypeToSchema(message.findFieldByName("repeated_field")) result.shouldBeTypeOf() result.items.shouldBeTypeOf() - (result.items as ReferenceDefinition).`$ref`.shouldBe(SimpleTestMessage.getDescriptor().name) + (result.items as ReferenceDefinition).`$ref`.shouldBe("$componentSlug/${SimpleTestMessage.getDescriptor().name}") } it("Repeated enum message should return ArrayDefinition") { @@ -93,7 +102,7 @@ class FieldDescriptiorConvertersKtTest : DescribeSpec({ val result: JsonSchema = fromNestedTypeToSchema(message.findFieldByName("repeated_field")) result.shouldBeTypeOf() result.items.shouldBeTypeOf() - (result.items as ReferenceDefinition).`$ref`.shouldBe(Corpus.getDescriptor().name) + (result.items as ReferenceDefinition).`$ref`.shouldBe("$componentSlug/${Corpus.getDescriptor().name}") } it("SimpleMapMessage message should return MapDefinition") { @@ -169,7 +178,7 @@ class FieldDescriptiorConvertersKtTest : DescribeSpec({ // Our nested field should be a reference result.shouldBeTypeOf() // Our nested field should be a reference to simplemessage - result.`$ref`.shouldBe(SimpleTestMessage.getDescriptor().name) + result.`$ref`.shouldBe("$componentSlug/${SimpleTestMessage.getDescriptor().name}") } it("Double nested message to schema") { @@ -201,11 +210,11 @@ class FieldDescriptiorConvertersKtTest : DescribeSpec({ // Our nested field should be a reference result.shouldBeTypeOf() // it should be a reference to our nested message - result.`$ref`.shouldBe(NestedMessage.getDescriptor().name) + result.`$ref`.shouldBe("$componentSlug/${NestedMessage.getDescriptor().name}") val nestedResult = (resultSchema[NestedMessage::class.createType()] as TypeDefinition).properties!!["nestedField"] nestedResult.shouldBeTypeOf() // Our nested message reference should be pointing to simpleTest message - nestedResult.`$ref`.shouldBe(SimpleTestMessage.getDescriptor().name) + nestedResult.`$ref`.shouldBe("$componentSlug/${SimpleTestMessage.getDescriptor().name}") // last but not least we should have definition for our SimpleTest message which is not a reference (resultSchema[SimpleTestMessage::class.createType()] as TypeDefinition).shouldNotBeTypeOf() } @@ -235,6 +244,39 @@ class FieldDescriptiorConvertersKtTest : DescribeSpec({ testMessageBasics(message) } } + + describe("Test spec generation") { + it("Generates simple message references") { + openApiTestAllSerializers( + "T0001__simpletestmessage_post.json", + testMessageBasics(SimpleTestMessage.getDefaultInstance()) + ) { testRoute() } + } + it("Generates enum references") { + openApiTestAllSerializers( + "T0002__enummessage_post.json", + testMessageBasics(EnumMessage.getDefaultInstance()) + ) { testRoute() } + } + it("Generates repeated type references") { + openApiTestAllSerializers( + "T0003__repeatedmessage_post.json", + testMessageBasics(RepeatedMessage.getDefaultInstance()) + ) { testRoute() } + } + it("Generates nested type references") { + openApiTestAllSerializers( + "T0004__nestedmessage_post.json", + testMessageBasics(NestedMessage.getDefaultInstance()) + ) { testRoute() } + } + it("Generates nested map type references") { + openApiTestAllSerializers( + "T0005__nestedmapmessage_post.json", + testMessageBasics(NestedMapMessage.getDefaultInstance()) + ) { testRoute() } + } + } }) /** @@ -256,3 +298,25 @@ fun testMessageBasics(message: GeneratedMessageV3): Map { } return resultSchema } + +private const val DEFAULT_RESPONSE_DESCRIPTION = "A Successful Endeavor" +private const val DEFAULT_REQUEST_DESCRIPTION = "You gotta send it" +private const val DEFAULT_PATH_SUMMARY = "Great Summary!" +private const val DEFAULT_PATH_DESCRIPTION = "testing more" +private inline fun Route.testRoute() { + install(NotarizedRoute()) { + post = PostInfo.builder { + summary(DEFAULT_PATH_SUMMARY) + description(DEFAULT_PATH_DESCRIPTION) + request { + requestType() + description(DEFAULT_REQUEST_DESCRIPTION) + } + response { + responseCode(HttpStatusCode.OK) + responseType() + description(DEFAULT_RESPONSE_DESCRIPTION) + } + } + } +} diff --git a/protobuf-java-converter/src/test/resources/T0001__simpletestmessage_post.json b/protobuf-java-converter/src/test/resources/T0001__simpletestmessage_post.json new file mode 100644 index 000000000..675c21fff --- /dev/null +++ b/protobuf-java-converter/src/test/resources/T0001__simpletestmessage_post.json @@ -0,0 +1,127 @@ +{ + "openapi": "3.1.0", + "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema", + "info": { + "title": "Test API", + "version": "1.33.7", + "description": "An amazing, fully-ish 😉 generated API spec", + "termsOfService": "https://example.com", + "contact": { + "name": "Homer Simpson", + "url": "https://gph.is/1NPUDiM", + "email": "chunkylover53@aol.com" + }, + "license": { + "name": "MIT", + "url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE" + } + }, + "servers": [ + { + "url": "https://myawesomeapi.com", + "description": "Production instance of my API" + }, + { + "url": "https://staging.myawesomeapi.com", + "description": "Where the fun stuff happens" + } + ], + "paths": { + "/": { + "post": { + "tags": [], + "summary": "Great Summary!", + "description": "testing more", + "parameters": [], + "requestBody": { + "description": "You gotta send it", + "required": true + }, + "responses": { + "200": { + "description": "A Successful Endeavor", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SimpleTestMessage" + } + } + } + } + }, + "deprecated": false + }, + "parameters": [] + } + }, + "webhooks": {}, + "components": { + "schemas": { + "SimpleTestMessage": { + "type": "object", + "properties": { + "myTestDouble": { + "type": "number", + "format": "double" + }, + "myTestFloat": { + "type": "number", + "format": "float" + }, + "myTestInt32": { + "type": "number", + "format": "int32" + }, + "myTestInt64": { + "type": "number", + "format": "int64" + }, + "myTestUint32": { + "type": "number", + "format": "int32" + }, + "myTestUint64": { + "type": "number", + "format": "int64" + }, + "myTestSint32": { + "type": "number", + "format": "int32" + }, + "myTestSint64": { + "type": "number", + "format": "int64" + }, + "myTestFixed32": { + "type": "number", + "format": "int32" + }, + "myTestFixed64": { + "type": "number", + "format": "int64" + }, + "myTestSfixed32": { + "type": "number", + "format": "int32" + }, + "myTestSfixed64": { + "type": "number", + "format": "int64" + }, + "myTestBool": { + "type": "boolean" + }, + "myTestBytes": { + "type": "string" + }, + "myTestString": { + "type": "string" + } + } + } + }, + "securitySchemes": {} + }, + "security": [], + "tags": [] +} diff --git a/protobuf-java-converter/src/test/resources/T0002__enummessage_post.json b/protobuf-java-converter/src/test/resources/T0002__enummessage_post.json new file mode 100644 index 000000000..fd64b0f5a --- /dev/null +++ b/protobuf-java-converter/src/test/resources/T0002__enummessage_post.json @@ -0,0 +1,86 @@ +{ + "openapi": "3.1.0", + "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema", + "info": { + "title": "Test API", + "version": "1.33.7", + "description": "An amazing, fully-ish 😉 generated API spec", + "termsOfService": "https://example.com", + "contact": { + "name": "Homer Simpson", + "url": "https://gph.is/1NPUDiM", + "email": "chunkylover53@aol.com" + }, + "license": { + "name": "MIT", + "url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE" + } + }, + "servers": [ + { + "url": "https://myawesomeapi.com", + "description": "Production instance of my API" + }, + { + "url": "https://staging.myawesomeapi.com", + "description": "Where the fun stuff happens" + } + ], + "paths": { + "/": { + "post": { + "tags": [], + "summary": "Great Summary!", + "description": "testing more", + "parameters": [], + "requestBody": { + "description": "You gotta send it", + "required": true + }, + "responses": { + "200": { + "description": "A Successful Endeavor", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnumMessage" + } + } + } + } + }, + "deprecated": false + }, + "parameters": [] + } + }, + "webhooks": {}, + "components": { + "schemas": { + "EnumMessage": { + "type": "object", + "properties": { + "corpus": { + "$ref": "#/components/schemas/Corpus" + } + } + }, + "Corpus": { + "type": "string", + "enum": [ + "CORPUS_UNSPECIFIED", + "CORPUS_UNIVERSAL", + "CORPUS_WEB", + "CORPUS_IMAGES", + "CORPUS_LOCAL", + "CORPUS_NEWS", + "CORPUS_PRODUCTS", + "CORPUS_VIDEO" + ] + } + }, + "securitySchemes": {} + }, + "security": [], + "tags": [] +} diff --git a/protobuf-java-converter/src/test/resources/T0003__repeatedmessage_post.json b/protobuf-java-converter/src/test/resources/T0003__repeatedmessage_post.json new file mode 100644 index 000000000..6c21cf13f --- /dev/null +++ b/protobuf-java-converter/src/test/resources/T0003__repeatedmessage_post.json @@ -0,0 +1,138 @@ +{ + "openapi": "3.1.0", + "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema", + "info": { + "title": "Test API", + "version": "1.33.7", + "description": "An amazing, fully-ish 😉 generated API spec", + "termsOfService": "https://example.com", + "contact": { + "name": "Homer Simpson", + "url": "https://gph.is/1NPUDiM", + "email": "chunkylover53@aol.com" + }, + "license": { + "name": "MIT", + "url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE" + } + }, + "servers": [ + { + "url": "https://myawesomeapi.com", + "description": "Production instance of my API" + }, + { + "url": "https://staging.myawesomeapi.com", + "description": "Where the fun stuff happens" + } + ], + "paths": { + "/": { + "post": { + "tags": [], + "summary": "Great Summary!", + "description": "testing more", + "parameters": [], + "requestBody": { + "description": "You gotta send it", + "required": true + }, + "responses": { + "200": { + "description": "A Successful Endeavor", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepeatedMessage" + } + } + } + } + }, + "deprecated": false + }, + "parameters": [] + } + }, + "webhooks": {}, + "components": { + "schemas": { + "RepeatedMessage": { + "type": "object", + "properties": { + "repeatedField": { + "items": { + "$ref": "#/components/schemas/SimpleTestMessage" + }, + "type": "array" + } + } + }, + "SimpleTestMessage": { + "type": "object", + "properties": { + "myTestDouble": { + "type": "number", + "format": "double" + }, + "myTestFloat": { + "type": "number", + "format": "float" + }, + "myTestInt32": { + "type": "number", + "format": "int32" + }, + "myTestInt64": { + "type": "number", + "format": "int64" + }, + "myTestUint32": { + "type": "number", + "format": "int32" + }, + "myTestUint64": { + "type": "number", + "format": "int64" + }, + "myTestSint32": { + "type": "number", + "format": "int32" + }, + "myTestSint64": { + "type": "number", + "format": "int64" + }, + "myTestFixed32": { + "type": "number", + "format": "int32" + }, + "myTestFixed64": { + "type": "number", + "format": "int64" + }, + "myTestSfixed32": { + "type": "number", + "format": "int32" + }, + "myTestSfixed64": { + "type": "number", + "format": "int64" + }, + "myTestBool": { + "type": "boolean" + }, + "myTestBytes": { + "type": "string" + }, + "myTestString": { + "type": "string" + } + } + } + }, + "securitySchemes": {} + }, + "security": [], + "tags": [] +} diff --git a/protobuf-java-converter/src/test/resources/T0004__nestedmessage_post.json b/protobuf-java-converter/src/test/resources/T0004__nestedmessage_post.json new file mode 100644 index 000000000..2f7ab4210 --- /dev/null +++ b/protobuf-java-converter/src/test/resources/T0004__nestedmessage_post.json @@ -0,0 +1,135 @@ +{ + "openapi": "3.1.0", + "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema", + "info": { + "title": "Test API", + "version": "1.33.7", + "description": "An amazing, fully-ish 😉 generated API spec", + "termsOfService": "https://example.com", + "contact": { + "name": "Homer Simpson", + "url": "https://gph.is/1NPUDiM", + "email": "chunkylover53@aol.com" + }, + "license": { + "name": "MIT", + "url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE" + } + }, + "servers": [ + { + "url": "https://myawesomeapi.com", + "description": "Production instance of my API" + }, + { + "url": "https://staging.myawesomeapi.com", + "description": "Where the fun stuff happens" + } + ], + "paths": { + "/": { + "post": { + "tags": [], + "summary": "Great Summary!", + "description": "testing more", + "parameters": [], + "requestBody": { + "description": "You gotta send it", + "required": true + }, + "responses": { + "200": { + "description": "A Successful Endeavor", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NestedMessage" + } + } + } + } + }, + "deprecated": false + }, + "parameters": [] + } + }, + "webhooks": {}, + "components": { + "schemas": { + "NestedMessage": { + "type": "object", + "properties": { + "nestedField": { + "$ref": "#/components/schemas/SimpleTestMessage" + } + } + }, + "SimpleTestMessage": { + "type": "object", + "properties": { + "myTestDouble": { + "type": "number", + "format": "double" + }, + "myTestFloat": { + "type": "number", + "format": "float" + }, + "myTestInt32": { + "type": "number", + "format": "int32" + }, + "myTestInt64": { + "type": "number", + "format": "int64" + }, + "myTestUint32": { + "type": "number", + "format": "int32" + }, + "myTestUint64": { + "type": "number", + "format": "int64" + }, + "myTestSint32": { + "type": "number", + "format": "int32" + }, + "myTestSint64": { + "type": "number", + "format": "int64" + }, + "myTestFixed32": { + "type": "number", + "format": "int32" + }, + "myTestFixed64": { + "type": "number", + "format": "int64" + }, + "myTestSfixed32": { + "type": "number", + "format": "int32" + }, + "myTestSfixed64": { + "type": "number", + "format": "int64" + }, + "myTestBool": { + "type": "boolean" + }, + "myTestBytes": { + "type": "string" + }, + "myTestString": { + "type": "string" + } + } + } + }, + "securitySchemes": {} + }, + "security": [], + "tags": [] +} diff --git a/protobuf-java-converter/src/test/resources/T0005__nestedmapmessage_post.json b/protobuf-java-converter/src/test/resources/T0005__nestedmapmessage_post.json new file mode 100644 index 000000000..9b343e3b8 --- /dev/null +++ b/protobuf-java-converter/src/test/resources/T0005__nestedmapmessage_post.json @@ -0,0 +1,146 @@ +{ + "openapi": "3.1.0", + "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema", + "info": { + "title": "Test API", + "version": "1.33.7", + "description": "An amazing, fully-ish 😉 generated API spec", + "termsOfService": "https://example.com", + "contact": { + "name": "Homer Simpson", + "url": "https://gph.is/1NPUDiM", + "email": "chunkylover53@aol.com" + }, + "license": { + "name": "MIT", + "url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE" + } + }, + "servers": [ + { + "url": "https://myawesomeapi.com", + "description": "Production instance of my API" + }, + { + "url": "https://staging.myawesomeapi.com", + "description": "Where the fun stuff happens" + } + ], + "paths": { + "/": { + "post": { + "tags": [], + "summary": "Great Summary!", + "description": "testing more", + "parameters": [], + "requestBody": { + "description": "You gotta send it", + "required": true + }, + "responses": { + "200": { + "description": "A Successful Endeavor", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NestedMapMessage" + } + } + } + } + }, + "deprecated": false + }, + "parameters": [] + } + }, + "webhooks": {}, + "components": { + "schemas": { + "NestedMapMessage": { + "type": "object", + "properties": { + "mapField": { + "additionalProperties": { + "type": "object", + "properties": { + "myVariable0": { + "$ref": "#/components/schemas/SimpleTestMessage" + }, + "myVariable1": { + "$ref": "#/components/schemas/SimpleTestMessage" + } + } + }, + "type": "object" + } + } + }, + "SimpleTestMessage": { + "type": "object", + "properties": { + "myTestDouble": { + "type": "number", + "format": "double" + }, + "myTestFloat": { + "type": "number", + "format": "float" + }, + "myTestInt32": { + "type": "number", + "format": "int32" + }, + "myTestInt64": { + "type": "number", + "format": "int64" + }, + "myTestUint32": { + "type": "number", + "format": "int32" + }, + "myTestUint64": { + "type": "number", + "format": "int64" + }, + "myTestSint32": { + "type": "number", + "format": "int32" + }, + "myTestSint64": { + "type": "number", + "format": "int64" + }, + "myTestFixed32": { + "type": "number", + "format": "int32" + }, + "myTestFixed64": { + "type": "number", + "format": "int64" + }, + "myTestSfixed32": { + "type": "number", + "format": "int32" + }, + "myTestSfixed64": { + "type": "number", + "format": "int64" + }, + "myTestBool": { + "type": "boolean" + }, + "myTestBytes": { + "type": "string" + }, + "myTestString": { + "type": "string" + } + } + } + }, + "securitySchemes": {} + }, + "security": [], + "tags": [] +}